Java面試--Spring技術要點--Spring AOP(面向切面程式設計)
33 Spring AOP的概念
面向切面的程式設計,是一種程式設計技術,是OOP(面向物件程式設計)的補充和完善。OOP的執行是一種從上往下的流程,並沒有從左到右的關係。因此在OOP程式設計中,會有大量的重複程式碼。而AOP則是將這些與業務無關的重複程式碼抽取出來,然後再嵌入到業務程式碼當中。常見的應用有:許可權管理、日誌、事務管理等。
實現AOP的技術,主要分為兩大類:一是採用動態代理技術,利用擷取訊息的方式,對該訊息進行裝飾,以取代原有物件行為的執行;二是採用靜態織入的方式,引入特定的語法建立“方面”,從而使得編譯器可以在編譯期間織入有關“方面”的程式碼。Spring AOP實現用的是動態代理的方式。
34 AOP的相關概念
- 切面/方面(Aspect):AOP核心就是切面,它將多個類的通用行為封裝成可重用的模組,該模組含有一組API提供橫切功能。如,一個日誌模組可以被稱作日誌的AOP切面。根據需求的不同,一個應用程式可以有若干切面。在SpringAOP中,切面通過帶有@Aspect註解的類實現。
- 連線點(Joinpoint):程式執行過程中明確的點,如方法的呼叫或特定的異常被丟擲。
- 通知/增強(Advice):在切入點上,可以應用的增強包括:around、before和throws。許多AOP框架包括Spring都是以攔截器做通知模型,維護一個“圍繞”連線點的攔截器鏈。Spring中定義了四個advice:BeforeAdvice,
AfterAdvice, ThrowAdvice和DynamicIntroductionAdvice。
- 切入點(Pointcut):將被增強(Advice)應用的連線點的集合(通常是Method集合)。Spring定義了Pointcut介面,用來組合MethodMatcher和ClassFilter,可以通過名字很清楚的理解,MethodMatcher是用來檢查目標類的方法是否可以被應用此通知,而ClassFilter是用來檢查Pointcut是否應該應用到目標類上。
- 目標物件(TargetObject):被通知(Advice)或被代理物件。
- AOP代理(AOP Proxy):AOP框架建立的物件,包含通知(Advice)。在Spring中,AOP代理可以是JDK動態代理或者CGLIB代理。
35 Spring AOP的增強/通知(Advice)型別
- Before Advice:在方法執行前執行。
- AfterAdvice:在方法執行之後呼叫的通知,無論方法執行是否成功。
- After ReturningAdvice:在方法執行後返回一個結果後執行。
- After ThrowingAdvice:在方法執行過程中丟擲異常的時候執行。
- Around Advice:在方法執行前後和丟擲異常時執行,相當於綜合了以上三種通知。(相關介面MethodIntercept)
- IntroductionAdvice(引入增強):引入通知是一種特殊的通知,它能將新的成員變數、成員方法引入到目標類中。它不能作用於任何切入點,因為它只作用於類層次,而不是方法層次。實現引入通知需要實現IntroductionAdvisor和IntroductionInterceptor介面。
36 Spring AOP 的關注點和橫切關注的區別
- 關注點是應用中一個模組的行為,一個關注點可能會被定義成一個我們想實現的一個功能。
- 橫切關注點是一個關注點,此關注點是整個應用都會使用的功能,並影響整個應用,比如日誌,安全和資料傳輸,幾乎應用的每個模組都需要的功能。因此這些都屬於橫切關注點。
37 引入(Introduction)的概念
引入(Introduction):新增方法或欄位到被通知的類。Spring允許引入新的介面到任何被通知的物件。例如,你可以使用一個引入使任何物件實現IsModified介面,來簡化快取。Spring中要使用Introduction,可有通過DelegatingIntroductionInterceptor來實現通知,通過DefaultIntroductionAdvisor來配置Advice和代理類要實現的介面。
38 Spring有幾種自動代理器
代理器有三類:
- 基於Bean的名字的自動代理建立器,例如BeanNameAutoProxyCreator
- 基於Advisor(切面)匹配機制的自動代理建立器。對spring容器中的所有的Advisor掃描,並將其應用到匹配的Bean中。例如DefaultAdvisorAutoProxyCreator
- 基於Bean中的AspjectJ註解標籤的自動代理建立器,例如AnnotationAwareAspectJAutoProxyCreator
所有的自動代理建立器,都是實現了BeanPostProcessor。spring容器在例項化Bean時,BeanPostProcessor會對其加工,對滿足匹配規則的Bean自動建立代理物件。
39 Spring織入概念
織入(Weaving):把切面(Aspect)應用到目標物件來建立新的代理物件的過程,織入一般發生在如下幾個時機:
- 編譯時:當一個類檔案被編譯時進行織入,這需要特殊的編譯器才可以做的到,例如AspectJ的織入編譯器。
- 類載入時:使用特殊的ClassLoader在目標類被載入到程式之前增強類的位元組程式碼。
- 執行時:切面在執行的某個時刻被織入,SpringAOP就是以這種方式織入切面的,原理應該是使用了動態代理技術。
40 Spring AOP的實現方式
1、經典的基於代理的AOP:使用Java程式碼實現,編寫Advice、PointCut,然後提供給Advisor使用。開啟自動代理後,即可在applicationContext中獲得增強後的bean。
2、@AspectJ註解驅動的切面:基於註解的開發(推薦使用),在專案中需要開啟AOP自動代理<aop:aspectj-autoproxy/>。
3、XML Schema方式:需要實現相應的增強介面,如BeforeAdvice、AfterAdvice等。然後利用一下配置如:
<aop:config>
<aop:aspect id="aspect" ref="xmlHandler">
<aop:pointcut id="pointUserMgr" expression="execution(* com.tgb.aop.*.find*(..))"/>
<aop:before method="doBefore" pointcut-ref="pointUserMgr"/>
<aop:after method="doAfter" pointcut-ref="pointUserMgr"/>
<aop:around method="doAround" pointcut-ref="pointUserMgr"/>
<aop:after-returning method="doReturn" pointcut-ref="pointUserMgr"/>
<aop:after-throwing method="doThrowing" throwing="ex" pointcut-ref="pointUserMgr"/>
</aop:aspect>
</aop:config>