《JAVA核心知識》學習筆記(6. Spring 原理)-5

它是一個全面的、企業應用開發一站式的解決方案,貫穿表現層、業務層、持久層。可是 Spring
仍然能夠和其餘的框架無縫整合。
6.1.1. Spring 特色
6.1.1.1. 輕量級
6.1.1.2. 控制反轉
6.1.1.3. 面向切面
6.1.1.4. 容器
6.1.1.5. 框架集合
 html

6.1.7. Spring IOC 原理
6.1.7.1. 概念
Spring 經過一個配置文件描述 Bean 及 Bean 之間的依賴關係,利用 Java 語言的反射功能實例化
Bean 並創建 Bean 之間的依賴關係。 Spring 的 IoC 容器在完成這些底層工做的基礎上,還提供
了 Bean 實例緩存、生命週期管理、 Bean 實例代理、事件發佈、資源裝載等高級服務
 java

6.1.7.2. Spring 容器高層視圖
Spring 啓動時讀取應用程序提供的 Bean 配置信息,並在 Spring 容器中生成一份相應的 Bean 配
置註冊表,而後根據這張註冊表實例化 Bean,裝配好 Bean 之間的依賴關係,爲上層應用提供準
備就緒的運行環境。 其中 Bean 緩存池爲 HashMap 實現
 web

6.1.7.3. IOC 容器實現
BeanFactory-框架基礎設施
BeanFactory 是 Spring 框架的基礎設施,面向 Spring 自己; ApplicationContext 面向使用
Spring 框架的開發者,幾乎全部的應用場合咱們都直接使用 ApplicationContext 而非底層
的 BeanFactory。
 spring

ApplicationContext 面向開發應用
ApplicationContext 由 BeanFactory 派 生 而 來 , 提 供 了 更 多 面 向 實 際 應 用 的 功 能 。
ApplicationContext 繼承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基礎
上,還經過多個其餘的接口擴展了 BeanFactory 的功能sql

 

1.1..1.1.1 BeanDefinitionRegistry 註冊表數據庫

1. Spring 配置文件中每個節點元素在 Spring 容器裏都經過一個 BeanDefinition 對象表示,
它描述了 Bean 的配置信息。而 BeanDefinitionRegistry 接口提供了向容器手工註冊
BeanDefinition 對象的方法。
1.1..1.1.2 BeanFactory 頂層接口

 

2. 位於類結構樹的頂端 ,它最主要的方法就是 getBean(String beanName),該方法從容器中
返回特定名稱的 Bean, BeanFactory 的功能經過其餘的接口獲得不斷擴展:
1.1..1.1.3 ListableBeanFactory

3. 該接口定義了訪問容器中 Bean 基本信息的若干方法,如查看 Bean 的個數、獲取某一類型
Bean 的配置名、查看容器中是否包括某一 Bean 等方法;
1.1..1.1.4 HierarchicalBeanFactory 父子級聯編程

4. 父子級聯 IoC 容器的接口,子容器能夠經過接口方法訪問父容器; 經過
HierarchicalBeanFactory 接口, Spring 的 IoC 容器能夠創建父子層級關聯的容器體系,子
容器能夠訪問父容器中的 Bean,但父容器不能訪問子容器的 Bean。 Spring 使用父子容器實
現了不少功能,好比在 Spring MVC 中,展示層 Bean 位於一個子容器中,而業務層和持久
層的 Bean 位於父容器中。這樣,展示層 Bean 就能夠引用業務層和持久層的 Bean,而業務
層和持久層的 Bean 則看不到展示層的 Bean
1.1..1.1.5 ConfigurableBeanFactory
5. 是一個重要的接口,加強了 IoC 容器的可定製性,它定義了設置類裝載器、屬性編輯器、容
器初始化後置處理器等方法;
 後端

6. 定義了將容器中的 Bean 按某種規則(如按名字匹配、按類型匹配等)進行自動裝配的方法;
1.1..1.1.7 SingletonBeanRegistry 運行期間註冊單例 Bean

7. 定義了容許在運行期間向容器註冊單實例 Bean 的方法;對於單實例( singleton)的 Bean
來講, BeanFactory 會緩存 Bean 實例,因此第二次使用 getBean() 獲取 Bean 時將直接從
IoC 容器的緩存中獲取 Bean 實例。 Spring 在 DefaultSingletonBeanRegistry 類中提供了一
個用於緩存單實例 Bean 的緩存器,它是一個用 HashMap 實現的緩存器, 單實例的 Bean 以
beanName 爲鍵保存在這個 HashMap 中。
1.1..1.1.8 依賴日誌框框
8. 在初始化 BeanFactory 時,必須爲其提供一種日誌框架,好比使用 Log4J, 即在類路徑下提
供 Log4J 配置文件,這樣啓動 Spring 容器纔不會報錯設計模式

 

ApplicationContext 面向開發應用
ApplicationContext 由 BeanFactory 派 生 而 來 , 提 供 了 更 多 面 向 實 際 應 用 的 功 能 。
ApplicationContext 繼承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基礎
上,還經過多個其餘的接口擴展了 BeanFactory 的功能:api

 

1. ClassPathXmlApplicationContext:默認從類路徑加載配置文件
2. FileSystemXmlApplicationContext:默認從文件系統中裝載配置文件
3. ApplicationEventPublisher:讓容器擁有發佈應用上下文事件的功能,包括容器啓動事
件、關閉事件等。
4. MessageSource:爲應用提供 i18n 國際化消息訪問的功能;
5. ResourcePatternResolver : 所 有 ApplicationContext 實現類都實現了相似於
PathMatchingResourcePatternResolver 的功能,能夠經過帶前綴的 Ant 風格的資源文
件路徑裝載 Spring 的配置文件。
6. LifeCycle:該接口是 Spring 2.0 加入的,該接口提供了 start()和 stop()兩個方法,主要
用於控制異步處理過程。在具體使用時,該接口同時被 ApplicationContext 實現及具體
Bean 實現, ApplicationContext 會將 start/stop 的信息傳遞給容器中全部實現了該接
口的 Bean,以達到管理和控制 JMX、任務調度等目的。
7. ConfigurableApplicationContext 擴展於 ApplicationContext, 它新增長了兩個主要
的方法: refresh()和 close(),讓 ApplicationContext 具備啓動、刷新和關閉應用上下
文的能力。在應用上下文關閉的狀況下調用 refresh()便可啓動應用上下文,在已經啓動
的狀態下,調用 refresh()則清除緩存並從新裝載配置信息,而調用 close()則可關閉應用
上下文
 

WebApplication 體系架構
WebApplicationContext 是專門爲 Web 應用準備的,它容許從相對於 Web 根目錄的
路徑中裝載配置文件完成初始化工做 。從 WebApplicationContext 中能夠得到
ServletContext 的引用, 整個 Web 應用上下文對象將做爲屬性放置到 ServletContext
中,以便 Web 應用環境能夠訪問 Spring 應用上下文
 

6.1.7.4. Spring Bean 做用域
Spring 3 中爲 Bean 定義了 5 中做用域, 分別爲 singleton(單例)、 prototype(原型)、
request、 session 和 global session, 5 種做用域說明以下:
singleton:單例模式(多線程下不安全)
1. singleton:單例模式, Spring IoC 容器中只會存在一個共享的 Bean 實例,不管有多少個
Bean 引用它,始終指向同一對象。 該模式在多線程下是不安全的。 Singleton 做用域是
Spring 中的缺省做用域,也能夠顯示的將 Bean 定義爲 singleton 模式,配置爲:
<bean id="userDao" class="com.ioc.UserDaoImpl" scope="singleton"/>
 

prototype:原型模式每次使用時建立
2. prototype:原型模式,每次經過 Spring 容器獲取 prototype 定義的 bean 時,容器都將建立
一個新的 Bean 實例,每一個 Bean 實例都有本身的屬性和狀態,而 singleton 全局只有一個對
象。根據經驗, 對有狀態的bean使用prototype做用域,而對無狀態的bean使用singleton
做用域
 

Request:一次 request 一個實例
3. request:在一次 Http 請求中,容器會返回該 Bean 的同一實例。而對不一樣的 Http 請求則會
產生新的 Bean,並且該 bean 僅在當前 Http Request 內有效,當前 Http 請求結束,該 bean
實例也將會被銷燬。
<bean id="loginAction" class="com.cnblogs.Login" scope="request"/>
 

session
4. session:在一次 Http Session 中,容器會返回該 Bean 的同一實例。而對不一樣的 Session 請
求則會建立新的實例,該 bean 實例僅在當前 Session 內有效。 同 Http 請求相同,每一次
session 請求建立新的實例,而不一樣的實例之間不共享屬性,且實例僅在本身的 session 請求
內有效,請求結束,則實例將被銷燬。
<bean id="userPreference" class="com.ioc.UserPreference" scope="session"/>

global Session
5. global Session:在一個全局的 Http Session 中,容器會返回該 Bean 的同一個實例,僅在
使用 portlet context 時有效
 

6.1.7.5. Spring Bean 生命週期
實例化
1. 實例化一個 Bean, 也就是咱們常說的 new。
IOC 依賴注入
2. 按照 Spring 上下文對實例化的 Bean 進行配置, 也就是 IOC 注入。
setBeanName 實現
3. 若是這個 Bean 已經實現了 BeanNameAware 接口,會調用它實現的 setBeanName(String)
方法,此處傳遞的就是 Spring 配置文件中 Bean 的 id 值
BeanFactoryAware 實現
4. 若是這個 Bean 已經實現了 BeanFactoryAware 接口,會調用它實現的 setBeanFactory,
setBeanFactory(BeanFactory)傳遞的是 Spring 工廠自身(能夠用這個方式來獲取其它 Bean,
只需在 Spring 配置文件中配置一個普通的 Bean 就能夠)。
 

ApplicationContextAware 實現
5. 若是這個 Bean 已經實現了 ApplicationContextAware 接口,會調用
setApplicationContext(ApplicationContext)方法,傳入 Spring 上下文(一樣這個方式也
能夠實現步驟 4 的內容,但比 4 更好,由於 ApplicationContext 是 BeanFactory 的子接
口,有更多的實現方法)
 

postProcessBeforeInitialization 接口實現-初始化預處理
6. 若是這個 Bean 關聯了 BeanPostProcessor 接口,將會調用
postProcessBeforeInitialization(Object obj, String s)方法, BeanPostProcessor 常常被用
做是 Bean 內容的更改,而且因爲這個是在 Bean 初始化結束時調用那個的方法,也能夠被應
用於內存或緩存技術。
init-method
7. 若是 Bean 在 Spring 配置文件中配置了 init-method 屬性會自動調用其配置的初始化方法
 

postProcessBeforeInitialization 接口實現-初始化預處理
6. 若是這個 Bean 關聯了 BeanPostProcessor 接口,將會調用
postProcessBeforeInitialization(Object obj, String s)方法, BeanPostProcessor 常常被用
做是 Bean 內容的更改,而且因爲這個是在 Bean 初始化結束時調用那個的方法,也能夠被應
用於內存或緩存技術。
init-method
7. 若是 Bean 在 Spring 配置文件中配置了 init-method 屬性會自動調用其配置的初始化方法。
postProcessAfterInitialization
8. 若是這個 Bean 關聯了 BeanPostProcessor 接口,將會調用
postProcessAfterInitialization(Object obj, String s)方法。
注: 以上工做完成之後就能夠應用這個 Bean 了,那這個 Bean 是一個 Singleton 的,因此一
般狀況下咱們調用同一個 id 的 Bean 會是在內容地址相同的實例,固然在 Spring 配置文件中
也能夠配置非 Singleton
 

Destroy 過時自動清理階段
9. 當 Bean 再也不須要時,會通過清理階段,若是 Bean 實現了 DisposableBean 這個接口,會調
用那個其實現的 destroy()方法;
destroy-method 自配置清理
10. 最後,若是這個 Bean 的 Spring 配置中配置了 destroy-method 屬性,會自動調用其配置的
銷燬方法
 

11. bean 標籤有兩個重要的屬性(init-method 和 destroy-method)。用它們你能夠本身定製
初始化和註銷方法。它們也有相應的註解(@PostConstruct 和@PreDestroy) 。
<bean id="" class="" init-method="初始化方法" destroy-method="銷燬方法">
 

6.1.7.6. Spring 依賴注入四種方式
構造器注入

/*帶參數,方便利用構造器進行注入*/
public CatDaoImpl(String message){
this. message = message;
}
<bean id="CatDaoImpl" class="com.CatDaoImpl">
<constructor-arg value=" message "></constructor-arg>
</bean

 

setter 方法注入

public class Id {
private int id;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
}
<bean id="id" class="com.id "> <property name="id" value="123"></property> </bean>

 

靜態工廠注入
靜態工廠顧名思義,就是經過調用靜態工廠的方法來獲取本身須要的對象,爲了讓 spring 管理所
有對象,咱們不能直接經過"工程類.靜態方法()"來獲取對象,而是依然經過 spring 注入的形式獲
取:

public class DaoFactory { //靜態工廠
public static final FactoryDao getStaticFactoryDaoImpl(){
return new StaticFacotryDaoImpl();
}
}
public class SpringAction {
private FactoryDao staticFactoryDao; //注入對象
//注入對象的 set 方法
public void setStaticFactoryDao(FactoryDao staticFactoryDao) {
this.staticFactoryDao = staticFactoryDao;
}
}
//factory-method="getStaticFactoryDaoImpl"指定調用哪一個工廠方法
<bean name="springAction" class=" SpringAction" >
<!--使用靜態工廠的方法注入對象,對應下面的配置文件-->
<property name="staticFactoryDao" ref="staticFactoryDao"></property>
</bean>
<!--此處獲取對象的方式是從工廠類中獲取靜態方法-->
<bean name="staticFactoryDao" class="DaoFactory"
factory-method="getStaticFactoryDaoImpl"></bean>

 

實例工廠
實例工廠的意思是獲取對象實例的方法不是靜態的,因此你須要首先 new 工廠類,再調用普通的
實例方法:

public class DaoFactory { //實例工廠
public FactoryDao getFactoryDaoImpl(){
return new FactoryDaoImpl();


13/04/2018 Page 128 of 283

}
}
public class SpringAction {
private FactoryDao factoryDao; //注入對象
public void setFactoryDao(FactoryDao factoryDao) {
this.factoryDao = factoryDao;
}
}
<bean name="springAction" class="SpringAction">
<!--使用實例工廠的方法注入對象,對應下面的配置文件-->
<property name="factoryDao" ref="factoryDao"></property>
</bean>
<!--此處獲取對象的方式是從工廠類中獲取實例方法-->
<bean name="daoFactory" class="com.DaoFactory"></bean>
<bean name="factoryDao" factory-bean="daoFactory"
factory-method="getFactoryDaoImpl"></bean>

6.1.7.7. 5 種不一樣方式的自動裝配
Spring 裝配包括手動裝配和自動裝配,手動裝配是有基於 xml 裝配、 構造方法、 setter 方法等
自動裝配有五種自動裝配的方式,能夠用來指導 Spring 容器用自動裝配方式來進行依賴注入。
1. no:默認的方式是不進行自動裝配,經過顯式設置 ref 屬性來進行裝配。
2. byName:經過參數名 自動裝配, Spring 容器在配置文件中發現 bean 的 autowire 屬性被設
置成 byname,以後容器試圖匹配、裝配和該 bean 的屬性具備相同名字的 bean。
3. byType:經過參數類型自動裝配, Spring 容器在配置文件中發現 bean 的 autowire 屬性被
設置成 byType,以後容器試圖匹配、裝配和該 bean 的屬性具備相同類型的 bean。若是有多
個 bean 符合條件,則拋出錯誤。
4. constructor:這個方式相似於 byType, 可是要提供給構造器參數,若是沒有肯定的帶參數
的構造器參數類型,將會拋出異常。
5. autodetect:首先嚐試使用 constructor 來自動裝配,若是沒法工做,則使用 byType 方式。
 

 

6.1.8. Spring AOP 原理
6.1.8.1. 概念
"橫切"的技術,剖解開封裝的對象內部,並將那些影響了多個類的公共行爲封裝到一個可重用模塊,
並將其命名爲"Aspect",即切面。所謂"切面",簡單說就是那些與業務無關,卻爲業務模塊所共
同調用的邏輯或責任封裝起來,便於減小系統的重複代碼,下降模塊之間的耦合度,並有利於未
來的可操做性和可維護性。
使用"橫切"技術, AOP 把軟件系統分爲兩個部分:核心關注點和橫切關注點。業務處理的主要流
程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特色是,他們常常發生
在覈心關注點的多處,而各處基本類似, 好比權限認證、日誌、事物。 AOP 的做用在於分離系統
中的各類關注點,將核心關注點和橫切關注點分離開來

 

AOP 主要應用場景有:
1. Authentication 權限
2. Caching 緩存
3. Context passing 內容傳遞
4. Error handling 錯誤處理
5. Lazy loading 懶加載
6. Debugging 調試
7. logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準
8. Performance optimization 性能優化
9. Persistence 持久化
10. Resource pooling 資源池
11. Synchronization 同步
12. Transactions 事務
 

6.1.8.2. AOP 核心概念
一、切面(aspect) : 類是對物體特徵的抽象,切面就是對橫切關注點的抽象
二、橫切關注點: 對哪些方法進行攔截,攔截後怎麼處理,這些關注點稱之爲橫切關注點。
三、鏈接點(joinpoint) : 被攔截到的點,由於 Spring 只支持方法類型的鏈接點,因此在 Spring
中鏈接點指的就是被攔截到的方法,實際上鍊接點還能夠是字段或者構造器。
四、切入點(pointcut) : 對鏈接點進行攔截的定義
五、通知(advice) : 所謂通知指的就是指攔截到鏈接點以後要執行的代碼, 通知分爲前置、後置、
異常、最終、環繞通知五類。
六、目標對象: 代理的目標對象
七、織入(weave) : 將切面應用到目標對象並致使代理對象建立的過程

八、引入(introduction) : 在不修改代碼的前提下,引入能夠在運行期爲類動態地添加一些方法
或字段。
 

6.1.8.1. AOP 兩種代理方式
Spring 提供了兩種方式來生成代理對象: JDKProxy 和 Cglib,具體使用哪一種方式 生成由
AopProxyFactory 根據 AdvisedSupport 對象的配置來決定。 默認的策略是若是目標類是接口,
則使用 JDK 動態代理技術,不然使用 Cglib 來生成代理。
JDK 動態接口代理
1. JDK 動態代理主要涉及到 java.lang.reflect 包中的兩個類: Proxy 和 InvocationHandler。
InvocationHandler 是一個接口,經過實現該接口定義橫切邏輯,並經過反射機制調用目標類
的代碼,動態將橫切邏輯和業務邏輯編制在一塊兒。 Proxy 利用 InvocationHandler 動態建立
一個符合某一接口的實例,生成目標類的代理對象。
 

CGLib 動態代理
2. : CGLib 全稱爲 Code Generation Library,是一個強大的高性能, 高質量的代碼生成類庫,
能夠在運行期擴展 Java 類與實現 Java 接口, CGLib 封裝了 asm,能夠再運行期動態生成新
的 class。和 JDK 動態代理相比較: JDK 建立代理有一個限制,就是隻能爲接口建立代理實例,
而對於沒有經過接口定義業務方法的類,則能夠經過 CGLib 建立動態代理。
 

CGLib 動態代理
2. : CGLib 全稱爲 Code Generation Library,是一個強大的高性能, 高質量的代碼生成類庫,
能夠在運行期擴展 Java 類與實現 Java 接口, CGLib 封裝了 asm,能夠再運行期動態生成新
的 class。和 JDK 動態代理相比較: JDK 建立代理有一個限制,就是隻能爲接口建立代理實例,
而對於沒有經過接口定義業務方法的類,則能夠經過 CGLib 建立動態代理。
 

6.1.8.2. 實現原理

@Aspect
public class TransactionDemo {
@Pointcut(value="execution(* com.yangxin.core.service.*.*.*(..))")
public void point(){
}
@Before(value="point()")
public void before(){
System.out.println("transaction begin");
}
@AfterReturning(value = "point()")
public void after(){
System.out.println("transaction commit");
}
@Around("point()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("transaction begin");
joinPoint.proceed();
System.out.println("transaction commit");
}
}

 

6.1.9. Spring MVC 原理
Spring 的模型-視圖-控制器(MVC)框架是圍繞一個 DispatcherServlet 來設計的,這個 Servlet
會把請求分發給各個處理器,並支持可配置的處理器映射、視圖渲染、本地化、時區與主題渲染
等,甚至還能支持文件上傳。

 

 

 

6.1.10. Spring Boot 原理
Spring Boot 是由 Pivotal 團隊提供的全新框架,其設計目的是用來簡化新 Spring 應用的初始搭
建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員再也不須要定義樣板化的
配置。經過這種方式, Spring Boot 致力於在蓬勃發展的快速應用開發領域(rapid application
development)成爲領導者。 其特色以下:
1. 建立獨立的 Spring 應用程序
2. 嵌入的 Tomcat,無需部署 WAR 文件
3. 簡化 Maven 配置
4. 自動配置 Spring
5. 提供生產就緒型功能,如指標,健康檢查和外部配置
6. 絕對沒有代碼生成和對 XML 沒有要求配置 [1]
 

 

6.1.11. JPA 原理
6.1.11.1. 事務
事務是計算機應用中不可或缺的組件模型,它保證了用戶操做的原子性 ( Atomicity )、一致性
( Consistency )、隔離性 ( Isolation ) 和持久性 ( Durabilily )。
6.1.11.2. 本地事務
緊密依賴於底層資源管理器(例如數據庫鏈接 ),事務處理侷限在當前事務資源內。此種事務處理
方式不存在對應用服務器的依賴,於是部署靈活卻沒法支持多數據源的分佈式事務。在數據庫連
接中使用本地事務

 

6.1.11.1. 分佈式事務
Java 事務編程接口(JTA: Java Transaction API)和 Java 事務服務 (JTS; Java Transaction
Service) 爲 J2EE 平臺提供了分佈式事務服務。分佈式事務(Distributed Transaction)包括事務
管理器( Transaction Manager)和一個或多個支持 XA 協議的資源管理器 ( Resource
Manager )。咱們能夠將資源管理器看作任意類型的持久化數據存儲;事務管理器承擔着全部事務
參與單元的協調與控制
 

6.1.11.1. 兩階段提交
兩階段提交主要保證了分佈式事務的原子性:即全部結點要麼全作要麼全不作,所謂的兩個階段
是指: 第一階段:準備階段;第二階段:提交階段
 

1 準備階段
事務協調者(事務管理器)給每一個參與者(資源管理器)發送 Prepare 消息,每一個參與者要麼直接返回
失敗(如權限驗證失敗), 要麼在本地執行事務,寫本地的 redo 和 undo 日誌,但不提交, 到達一
種「萬事俱備,只欠東風」的狀態。
2 提交階段:
若是協調者收到了參與者的失敗消息或者超時,直接給每一個參與者發送回滾(Rollback)消息;不然,
發送提交(Commit)消息;參與者根據協調者的指令執行提交或者回滾操做,釋放全部事務處理過
程中使用的鎖資源。 (注意:必須在最後階段釋放鎖資源)
 

將提交分紅兩階段進行的目的很明確,就是儘量晚地提交事務,讓事務在提交前儘量地完成
全部能完成的工做
 

6.1.12. Mybatis 緩存
Mybatis 中有一級緩存和二級緩存,默認狀況下一級緩存是開啓的,並且是不能關閉的。一級緩存
是指 SqlSession 級別的緩存,當在同一個 SqlSession 中進行相同的 SQL 語句查詢時,第二次以
後的查詢不會從數據庫查詢,而是直接從緩存中獲取,一級緩存最多緩存 1024 條 SQL。二級緩存
是指能夠跨 SqlSession 的緩存。 是 mapper 級別的緩存,對於 mapper 級別的緩存不一樣的
sqlsession 是能夠共享的

 

 

6.1.12.1. Mybatis 的一級緩存原理(sqlsession 級別)
第一次發出一個查詢 sql, sql 查詢結果寫入 sqlsession 的一級緩存中,緩存使用的數據結構是一
個 map。
key: MapperID+offset+limit+Sql+全部的入參
value:用戶信息
同一個 sqlsession 再次發出相同的 sql,就從緩存中取出數據。若是兩次中間出現 commit 操做
(修改、添加、刪除),本 sqlsession 中的一級緩存區域所有清空,下次再去緩存中查詢不到所
以要從數據庫查詢, 從數據庫查詢到再寫入緩存
 

6.1.12.2. 二級緩存原理(mapper 基本)
二級緩存的範圍是 mapper 級別(mapper 同一個命名空間), mapper 以命名空間爲單位建立緩
存數據結構,結構是 map。 mybatis 的二級緩存是經過 CacheExecutor 實現的。 CacheExecutor
13/04/2018 Page 139 of 283
實際上是 Executor 的代理對象。全部的查詢操做,在 CacheExecutor 中都會先匹配緩存中是否存
在,不存在則查詢數據庫。
key: MapperID+offset+limit+Sql+全部的入參
具體使用須要配置
 

具體使用須要配置:
1. Mybatis 全局配置中啓用二級緩存配置
2. 在對應的 Mapper.xml 中配置 cache 節點
3. 在對應的 select 查詢節點中添加 useCache=true
 

6.1.13. Tomcat 架構
http://www.importnew.com/21112.html
 

7. 微服務
7.1.1. 服務註冊發現
服務註冊就是維護一個登記簿,它管理系統內全部的服務地址。當新的服務啓動後,它會向登記
簿交待本身的地址信息。服務的依賴方直接向登記簿要 Service Provider 地址就好了。當下用於服
務註冊的工具很是多 ZooKeeper, Consul, Etcd, 還有 Netflix 家的 eureka 等。 服務註冊有兩種
形式:客戶端註冊和第三方註冊。
7.1.1.1. 客戶端註冊(zookeeper)
客戶端註冊是服務自身要負責註冊與註銷的工做。當服務啓動後向註冊中心註冊自身,當服務下
線時註銷本身。期間還須要和註冊中心保持心跳。心跳不必定要客戶端來作,也能夠由註冊中心
負責(這個過程叫探活)。這種方式的缺點是註冊工做與服務耦合在一塊兒,不一樣語言都要實現一
套註冊邏輯。
 

7.1.1.1. 客戶端註冊(zookeeper)
客戶端註冊是服務自身要負責註冊與註銷的工做。當服務啓動後向註冊中心註冊自身,當服務下
線時註銷本身。期間還須要和註冊中心保持心跳。心跳不必定要客戶端來作,也能夠由註冊中心
負責(這個過程叫探活)。這種方式的缺點是註冊工做與服務耦合在一塊兒,不一樣語言都要實現一
套註冊邏輯。

7.1.1.2. 第三方註冊(獨立的服務 Registrar)
第三方註冊由一個獨立的服務Registrar負責註冊與註銷。當服務啓動後以某種方式通知Registrar,
而後 Registrar 負責向註冊中心發起註冊工做。同時註冊中心要維護與服務之間的心跳,當服務不
可用時,向註冊中心註銷服務。這種方式的缺點是 Registrar 必須是一個高可用的系統,不然註冊
工做無法進展。
 

7.1.1.3. 客戶端發現
客戶端發現是指客戶端負責查詢可用服務地址,以及負載均衡的工做。這種方式最方便直接,而
且也方便作負載均衡。再者一旦發現某個服務不可用當即換另一個,很是直接。缺點也在於多
語言時的重複工做,每一個語言實現相同的邏輯。
 

7.1.1.4. 服務端發現
服務端發現須要額外的 Router 服務,請求先打到 Router,而後 Router 負責查詢服務與負載均衡。
這種方式雖然沒有客戶端發現的缺點,可是它的缺點是保證 Router 的高可用
 

7.1.1.5. Consul
7.1.1.6. Eureka
7.1.1.7. SmartStack
7.1.1.8. Etcd

 

7.1.2. API 網關
API Gateway 是一個服務器,也能夠說是進入系統的惟一節點。這跟面向對象設計模式中的
Facade 模式很像。 API Gateway 封裝內部系統的架構,而且提供 API 給各個客戶端。它還可能有
其餘功能,如受權、監控、負載均衡、緩存、請求分片和管理、靜態響應處理等。下圖展現了一
個適應當前架構的 API Gateway
 

API Gateway 負責請求轉發、合成和協議轉換。全部來自客戶端的請求都要先通過 API Gateway,
而後路由這些請求到對應的微服務。 API Gateway 將常常經過調用多個微服務來處理一個請求以
及聚合多個服務的結果。它能夠在 web 協議與內部使用的非 Web 友好型協議間進行轉換,如
HTTP 協議、 WebSocket 協議。
 

7.1.2.1. 請求轉發
服務轉發主要是對客戶端的請求安裝微服務的負載轉發到不一樣的服務上
7.1.2.2. 響應合併
把業務上須要調用多個服務接口才能完成的工做合併成一次調用對外統一提供服務。
7.1.2.3. 協議轉換
重點是支持 SOAP, JMS, Rest 間的協議轉換。
7.1.2.4. 數據轉換
重點是支持 XML 和 Json 之間的報文格式轉換能力(可選)
13/04/2018 Page 144 of 283
7.1.2.5. 安全認證
1. 基於 Token 的客戶端訪問控制和安全策略
2. 傳輸數據和報文加密,到服務端解密,須要在客戶端有獨立的 SDK 代理包
3. 基於 Https 的傳輸加密,客戶端和服務端數字證書支持
4. 基於 OAuth2.0 的服務安全認證(受權碼,客戶端,密碼模式等)
 

 

7.1.3. 配置中心
配置中心通常用做系統的參數配置,它須要知足以下幾個要求:高效獲取、實時感知、分佈式訪
問。
7.1.3.1. zookeeper 配置中心
實現的架構圖以下所示,採起數據加載到內存方式解決高效獲取的問題,藉助 zookeeper 的節點
監聽機制來實現實時感知。
 

7.1.4. 事件調度(kafka)
消息服務和事件的統一調度,經常使用用 kafka , activemq 等
 

7.1.5. 服務跟蹤(starter-sleuth)
隨着微服務數量不斷增加,須要跟蹤一個請求從一個微服務到下一個微服務的傳播過程, Spring
Cloud Sleuth 正是解決這個問題,它在日誌中引入惟一 ID,以保證微服務調用之間的一致性,這
樣你就能跟蹤某個請求是如何從一個微服務傳遞到下一個。
 

1. 爲了實現請求跟蹤,當請求發送到分佈式系統的入口端點時,只須要服務跟蹤框架爲該請求
建立一個惟一的跟蹤標識,同時在分佈式系統內部流轉的時候,框架始終保持傳遞該惟一標
識,直到返回給請求方爲止, 這個惟一標識就是前文中提到的 Trace ID。經過 Trace ID 的記
錄,咱們就能將全部請求過程日誌關聯起來。
2. 爲了統計各處理單元的時間延遲,當請求達到各個服務組件時,或是處理邏輯到達某個狀態
時,也經過一個惟一標識來標記它的開始、具體過程以及結束,該標識就是咱們前文中提到
的 Span ID, 對於每一個 Span 來講,它必須有開始和結束兩個節點,經過記錄開始 Span 和結
束 Span 的時間戳,就能統計出該 Span 的時間延遲,除了時間戳記錄以外,它還能夠包含一
些其餘元數據,好比:事件名稱、請求信息等。
3. 在快速入門示例中,咱們輕鬆實現了日誌級別的跟蹤信息接入,這徹底歸功於spring-cloudstarter-sleuth 組件的實現。在 Spring Boot 應用中,經過在工程中引入 spring-cloudstarter-sleuth 依賴以後, 它會自動的爲當前應用構建起各通訊通道的跟蹤機制,好比:
 經過諸如 RabbitMQ、 Kafka(或者其餘任何 Spring Cloud Stream 綁定器實現的消息
中間件)傳遞的請求。
 經過 Zuul 代理傳遞的請求。
 經過 RestTemplate 發起的請求。
 

7.1.6. 服務熔斷(Hystrix)
在微服務架構中一般會有多個服務層調用,基礎服務的故障可能會致使級聯故障,進而形成整個
系統不可用的狀況,這種現象被稱爲服務雪崩效應。服務雪崩效應是一種因「服務提供者」的不
可用致使「服務消費者」的不可用,並將不可用逐漸放大的過程。
熔斷器的原理很簡單,如同電力過載保護器。它能夠實現快速失敗,若是它在一段時間內偵測到
許多相似的錯誤, 會強迫其之後的多個調用快速失敗,再也不訪問遠程服務器,從而防止應用程序
不斷地嘗試執行可能會失敗的操做,使得應用程序繼續執行而不用等待修正錯誤,或者浪費 CPU
時間去等到長時間的超時產生。熔斷器也可使應用程序可以診斷錯誤是否已經修正,若是已經
修正,應用程序會再次嘗試調用操做
 

7.1.6.1. Hystrix 斷路器機制
斷路器很好理解, 當 Hystrix Command 請求後端服務失敗數量超過必定比例(默認 50%), 斷路器會
切換到開路狀態(Open). 這時全部請求會直接失敗而不會發送到後端服務. 斷路器保持在開路狀態
一段時間後(默認 5 秒), 自動切換到半開路狀態(HALF-OPEN). 這時會判斷下一次請求的返回狀況,
若是請求成功, 斷路器切回閉路狀態(CLOSED), 不然從新切換到開路狀態(OPEN). Hystrix 的斷路器
就像咱們家庭電路中的保險絲, 一旦後端服務不可用, 斷路器會直接切斷請求鏈, 避免發送大量無效
請求影響系統吞吐量, 而且斷路器有自我檢測並恢復的能力。
 

7.1.7. API 管理
SwaggerAPI 管理工具。

http://www.javashuo.com/article/p-kzbuvdhv-do.html8

相關文章
相關標籤/搜索