Spring in Action 入門之面向切面編程AOP


注明:這篇文章一是當成學習筆記,二是給大家提供另一個快速理解學習Spring的參考。歡迎留言討論,持續更新中~

(該部分是Spring的面向切面編程AOP)

第四章 通知Bean

在軟件編程中,散布於程序中多個地點的函數被稱為“交叉事務”(日志管理、權限控制等)。從概念上來說,它們一般是與程序業務邏輯分開的,但經常卻是直接嵌入其中的。把這些交叉事務與業務邏輯分離開正式面向切面編程(AOP)的作用所在,由此引入面向切面編程...

Spring AOP的實現原理是:創建一個代理Bean,綁定通知者類(通知者類包含切面代碼切點),匹配相應的方法,在目標代碼中嵌入執行切面的代碼。


 

1. 通過配置來詳細說明下Spring AOP的流程:(為了弄清楚原理,所以從配置講起,雖然目前這種方式已經不常用了,Spring 2.0提供了更加優雅的解決方案。)

代理Bean的配置,ProxyFactoryBean

<bean id="duke" class="org.springframework......ProxyFactoryBean">
    <property name="target" ref="dukeTarget" />
    <property name="interceptorNames" value="audienceAdvisor" />
    <property name="proxyInterfaces" value="com.....Performer" />
</bean>
  • target:這個屬性告訴ProxyFactoryBean哪個Bean需要被代理,通俗點就是哪個Bean需要運用切面代碼,target配置的就是目標代碼。
  • interceptorNames:配置通知者,通知者可以按照如下方式配置:
<bean id="audienceAdvisor" class="org.springframe....AspectJExpressionPointcutAdvisor">
    <property name="advise" ref="audienceAdvice" /> //通知者Bean,主要包含切面代碼,需要實現MethodBeforeAdvice等接口,用來表示在目標代碼執行前、后、拋出異常時候的切面代碼
    <property name="expression" value="execution(* *.perform(..))" /> //AspectJ的切點匹配表達式,用來監測當目標代碼執行perform操作時候,觸發切面代碼
</bean>
  • proxyInterfaces:應該代理目標代碼中的哪個接口(這個屬性其實有點重復,切點表達式基本可以匹配了,自動代理就是基於這個的升級)

2. AspectJ通過注解提供了另外一個把POJO類注解成切面的方式,比較簡潔,直接在Java代碼中寫注解,額外的配置就是在Spring的上下文中聲明一個自動代理的Bean,這樣才能知道如何把@AspectJ注解的Bean轉化為代理通知。

import org.aspectJ.lang.annotation.Aspect;

@Aspect //聲明切面
public class Audience {

@Pointcut("execution(* *.perform(..))") //定義切點
public void performance() {}

@Before("performance()")  //切點之前執行
public ....      

@AfterReturning("performance()")  //切點之后執行
public ...

@AfterThrowing("performance()")  //切點拋出異常后執行
public ...
}

3. Aspect這種切面聲明的方式已經直接在代碼中修改,如果要把一個普通的POJO轉化成切面,那就必須獲得源代碼,然后改變源代碼,這點是我們不希望看到的。有沒有辦法,讓我們可以引用任何Bean,作為切面呢? Spring 2.0提供了<aop:aspect>,是一個把POJO轉化為切面的優雅方案。

<aop:config>
<aop:aspect ref="audience">  //切面代碼Bean
<aop:pointcut id="performance" expression="excution(* *.performance(..))"  />   //定義切點

<aop:before  method="..."  pointcut-ref="performance" />  //切面代碼具體方法,在切點前執行(下同)
<aop:after-returnning  method="..."  pointcut-ref="performance" />
<aop:after-throwing  method="..."  pointcut-ref="performance" />

</aop:aspect>
</aop:config>

 


總結:雖然Spring AOP對於大多數切面程序來說是足夠了,但Java的構造函數與普通方法是有區別的(不能被繼承),這使得Spring基於代理的AOP不能實現對象創建過程的通知。AspectJ實現的切面控制獨立於Spring,提供了Spring AOP不可能實現的多種切點類型,這方面特性一般也沒用到,有需要的朋友可以深入研究。

 

 

萌萌的IT人,IT人的樂園


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM