1、What?
AOP,面向切面編程編程
- OOP面向對象編程的模式,OOP的主要功能是數據封裝、繼承和多態。OOP把系統看做多個對象的交互
- AOP是一種新的編程方式,AOP把系統分解爲不一樣的關注點,或者稱之爲切面
相關概念:代理
- Aspect:切面,即一個橫跨多個核心邏輯的功能,或者稱之爲系統關注點
- Joinpoint:鏈接點,即定義在應用程序流程的何處插入切面的執行
- Pointcut:切入點,即一組鏈接點的集合
- Weaving:織入,指將切面整合到程序的執行流程中
- Target Object:目標對象,即真正執行業務的核心邏輯對象
攔截器有如下類型:對象
- @Before:這種攔截器先執行攔截代碼,再執行目標代碼。若是攔截器拋異常,那麼目標代碼就不執行了;
- @After:這種攔截器先執行目標代碼,再執行攔截器代碼。不管目標代碼是否拋異常,攔截器代碼都會執行;
- @AfterReturning:和@After不一樣的是,只有當目標代碼正常返回時,才執行攔截器代碼;
- @AfterThrowing:和@After不一樣的是,只有當目標代碼拋出了異常時,才執行攔截器代碼;
- @Around:能徹底控制目標代碼是否執行,並能夠在執行先後、拋異常後執行任意攔截代碼,能夠說是包含了上面全部功能。
2、How?
生產中使用註解裝配AOP,不要使用AspectJ的相似execution( xxx.Xyz.(..))這樣的複雜註解繼承
3、Why?
對於AOP的織入,有3種方式:接口
- 編譯期:在編譯時,由編譯器把切面調用編譯進字節碼,這種方式須要定義新的關鍵字並擴展編譯器,AspectJ就擴展了Java編譯器,使用關鍵字aspect來實現織入;
- 類加載器:在目標類被裝載到JVM時,經過一個特殊的類加載器,對目標類的字節碼從新「加強」;
- 運行期:目標對象和切面都是普通Java類,經過JVM的動態代理功能或者第三方庫實現運行期動態織入。
Spring的AOP實現就是基於動態代理:get
- Spring對接口類型使用JDK動態代理,對普通類使用CGLIB建立子類。若是一個Bean的class是final,Spring將沒法爲其建立子類。
自動加super()的功能是Java編譯器實現的,它發現你沒加,就自動給加上,發現你加錯了,就報編譯錯誤。但實際上,若是直接構造字節碼,一個類的構造方法中,不必定非要調用super()。Spring使用CGLIB構造的Proxy類,是直接生成字節碼,並無源碼-編譯-字節碼這個步驟,因此:編譯器
- Spring經過CGLIB建立的代理類,不會初始化代理類自身繼承的任何成員變量,包括final類型的成員變量!