spring原理(二)

Spring APO 原理

    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 事務

 

2. AOP 核心概念

1、切面(aspect):類是對物體特徵的抽象,切面就是對橫切關注點的抽象

2、橫切關注點:對哪些方法進行攔截,攔截後怎麼處理,這些關注點稱之爲橫切關注點。

3、連接點(joinpoint):被攔截到的點,因爲 Spring 只支持方法類型的連接點,所以在 Spring中連接點指的就是被攔截到的方法,實際上連接點還可以是字段或者構造器。

4、切入點(pointcut):對連接點進行攔截的定義

5、通知(advice):所謂通知指的就是指攔截到連接點之後要執行的代碼,通知分爲前置、後置、異常、最終、環繞通知五類。

6、目標對象:代理的目標對象

7、織入(weave):將切面應用到目標對象並導致代理對象創建的過程

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

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 創建動態代理。

@Aspectpublic 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");}}

 

Spring MVC 原理

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

1. MVC 流程

Http 請求到 DispatcherServlet

   (1) 客戶端請求提交到 DispatcherServlet

HandlerMapping 尋找處理器

   (2) 由 DispatcherServlet 控制器查詢一個或多個 HandlerMapping,找到處理請求的Controller。

調用處理器 Controller

            (3) DispatcherServlet 將請求提交到 Controller。

 

Controller 調用業務邏輯處理後,返回 ModelAndView

        (4)(5)調用業務處理和返回結果:Controller 調用業務邏輯處理後,返回 ModelAndView。

DispatcherServlet 查詢 ModelAndView

           (6)(7)處理視圖映射並返回模型:DispatcherServlet 查詢一個或多個 ViewResoler 視圖解析器,找到 ModelAndView 指定的視圖。

ModelAndView 反饋瀏覽器 HTTP

            (8) Http 響應:視圖負責將結果顯示到客戶端

 

    1. MVC 常用註解

        

 

Spring Boot 原理

        Spring Boot 是由 Pivotal 團隊提供的全新框架,其設計目的是用來簡化新 Spring 應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。通過這種方式,Spring Boot 致力於在蓬勃發展的快速應用開發領域(rapid application development)成爲領導者。其特點如下:

    1. 創建獨立的 Spring 應用程序

    2. 嵌入的 Tomcat,無需部署 WAR 文件

    3. 簡化 Maven 配置

    4. 自動配置 Spring

    5. ᨀ供生產就緒型功能,如指標,健康檢查和外部配置

    6. 絕對沒有代碼生成和對 XML 沒有要求配置 [1]

 

JPA 原理

    1. 事務

    事務是計算機應用中不可或缺的組件模型,它保證了用戶操作的原子性 ( Atomicity )、一致性( Consistency )、隔離性 ( Isolation ) 和持久性 ( Durabilily )。

    2. 本地事務

    緊密依賴於底層資源管理器(例如數據庫連接 ),事務處理侷限在當前事務資源內。此種事務處理方式不存在對應用服務器的依賴,因而部署靈活卻無法支持多數據源的分佈式事務。在數據庫連接中使用本地事務示例如下:

public void transferAccount() { Connection conn = null; Statement stmt = null; try{ conn = getDataSource().getConnection(); // 將自動ᨀ交設置爲 false,若設置爲 true 則數據庫將會把每一次數據更新認定爲一個事務並自動ᨀ交conn.setAutoCommit(false);stmt = conn.createStatement(); // 將 A 賬戶中的金額減少 500stmt.execute("update t_account set amount = amount - 500 where account_id = 'A'");// 將 B 賬戶中的金額增加 500 stmt.execute("update t_account set amount = amount + 500 where account_id = 'B'");// ᨀ交事務 conn.commit(); // 事務ᨀ交:轉賬的兩步操作同時成功} catch(SQLException sqle){ // 發生異常,回滾在本事務中的操做 conn.rollback();// 事務回滾:轉賬的兩步操作完全撤銷 stmt.close();  conn.close(); } }

  3. 分佈式事務  

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

public void transferAccount() { UserTransaction userTx = null; Connection connA = null; Statement stmtA = null; Connection connB = null; Statement stmtB = null; try{ // 獲得 Transaction 管理對象userTx = (UserTransaction)getContext().lookup("java:comp/UserTransaction"); connA = getDataSourceA().getConnection();// 從數據庫 A 中取得數據庫連接connB = getDataSourceB().getConnection();// 從數據庫 B 中取得數據庫連接userTx.begin(); // 啓動事務stmtA = connA.createStatement();// 將 A 賬戶中的金額減少 500 stmtA.execute("update t_account set amount = amount - 500 where account_id = 'A'");// 將 B 賬戶中的金額增加 500 stmtB = connB.createStatement();stmtB.execute("update t_account set amount = amount + 500 where account_id = 'B'");userTx.commit();// 提交事務// 事務提交:轉賬的兩步操作同時成功(數據庫 A 和數據庫 B 中的數據被同時更新)} catch(SQLException sqle){ // 發生異常,回滾在本事務中的操縱 userTx.rollback();// 事務回滾:數據庫 A 和數據庫 B 中的數據更新被同時撤銷} catch(Exception ne){ } }

4. 兩階段提交

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

       1 準備階段

        事務協調者(事務管理器)給每個參與者(資源管理器)發送 Prepare 消息,每個參與者要麼直接返回失敗(如權限驗證失敗),要麼在本地執行事務,寫本地的 redo 和 undo 日誌,但不提交,到達一種“萬事俱備,只欠東風”的狀態。

        2 提交階段:

        如果協調者收到了參與者的失敗消息或者超時,直接給每個參與者發送回滾(Rollback)消息;否則,發送提交(Commit)消息;參與者根據協調者的指令執行提交或者回滾操作,釋放所有事務處理過程中使用的鎖資源。(注意:必須在最後階段釋放鎖資源)

 

將提交分成兩階段進行的目的很明確,就是儘可能晚地提交事務,讓事務在提交前儘可能地完成所有能完成的工作。

 

Mybatis 緩存

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

        1. Mybatis 的一級緩存原理(sqlsession 級別)

        第一次發出一個查詢 sql,sql 查詢結果寫入 sqlsession 的一級緩存中,緩存使用的數據結構是一個 map。

key:MapperID+offset+limit+Sql+所有的入參

value:用戶信息

同一個 sqlsession 再次發出相同的 sql,就從緩存中取出數據。如果兩次中間出現 commit 操作(修改、添加、刪除),本 sqlsession 中的一級緩存區域全部清空,下次再去緩存中查詢不到所以要從數據庫查詢,從數據庫查詢到再寫入緩存。

        2. 二級緩存原理(mapper 基本)

            二級緩存的範圍是 mapper 級別(mapper 同一個命名空間),mapper 以命名空間爲單位創建緩存數據結構,結構是 map。mybatis 的二級緩存是通過 CacheExecutor 實現的。CacheExecutor其實是 Executor 的代理對象。所有的查詢操作,在 CacheExecutor 中都會先匹配緩存中是否存在,不存在則查詢數據庫。key:MapperID+offset+limit+Sql+所有的入參

具體使用需要配置:

    1. Mybatis 全局配置中啓用二級緩存配置

    2. 在對應的 Mapper.xml 中配置 cache 節點

    3. 在對應的 select 查詢節點中添加 useCache=true

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章