Spring的AOP配置詳解
AOP是一種切面程式設計的思想,縱向抽取,橫向重複使其核心。Spring提供了對AOP程式設計的支援,原理是Spring在物件建立時可以動態生成代理物件,而且對這個物件的指定進行邏輯加強。下面說一下AOP怎麼寫在配置檔案中。
假設我們現在的需求是在操作資料庫的程式碼前後加上事務處理。
首先編寫目標物件類
public class UserServiceImpl implements UserService { @Override public void save() { System.out.println("儲存使用者!"); } @Override public void delete() { System.out.println("刪除使用者!"); } @Override public void update() { System.out.println("更新使用者!"); } @Override public void find() { System.out.println("查詢使用者!"); } }
編寫通知類
public class MyAdvice { //前置通知 public void before(){ System.out.println("這是前置通知!!"); } //後置通知 public void afterReturning(){ System.out.println("這是後置通知(如果出現異常不會呼叫)!!"); } //環繞通知 public Object around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("這是環繞通知之前的部分!!"); Object proceed = pjp.proceed();//呼叫目標方法 System.out.println("這是環繞通知之後的部分!!"); return proceed; } //異常通知 public void afterException(){ System.out.println("出事啦!出現異常了!!"); } //後置通知 public void after(){ System.out.println("這是後置通知(出現異常也會呼叫)!!"); } }
配置檔案applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <!-- 準備工作: 匯入aop(約束)名稱空間 --> <!-- 1.配置目標物件 --> <bean name="userService" class="test.service.UserServiceImpl" ></bean> <!-- 2.配置通知物件 --> <bean name="myAdvice" class="test_springaop.MyAdvice" ></bean> <!-- 3.配置將通知織入目標物件 --> <aop:config> <!-- 配置切入點 --> <aop:pointcut expression="execution(* test.service.*ServiceImpl.*(..))" id="pc"/> <aop:aspect ref="myAdvice" > <!-- 指定名為before方法作為前置通知 --> <aop:before method="before" pointcut-ref="pc" /> <!-- 後置 --> <aop:after-returning method="afterReturning" pointcut-ref="pc" /> <!-- 環繞通知 --> <aop:around method="around" pointcut-ref="pc" /> <!-- 異常攔截通知 --> <aop:after-throwing method="afterException" pointcut-ref="pc"/> <!-- 後置 --> <aop:after method="after" pointcut-ref="pc"/> </aop:aspect> </aop:config> </beans>
開始配置
首先要匯入SpringAOP的名稱空間,然後把目標物件和通知類配置到配置檔案中,然後配置將通知織入到目標物件。在<config>的標籤下進行配置,先配置切入點<pointcut>,切入點是你想要增強和已經增強的方法,id屬性指定這個切點的一個名稱,expression屬性必須用表示式來寫,格式為execution(完整方法名),如(public void test.service.UserServiceImpl.save()),表示一個公用的返回值為void的方法save()作為想要增強的方法,public可以不寫,因為這是個預設值,而且增強private方法意義不太大。在表示式中,如果我們想一次對多個方法進行增強,可以用*代替一些文字,達到通配的效果,例如
void test.service.UserServiceImpl.save():去掉public
* test.service.UserServiceImpl.save():返回值任意
* test.service.UserServiceImpl.*():返回值任意且對est.service.UserServiceImp類下所有空參方法進行增強。
*test.service.*ServiceImpl.*(..):返回值任意且對est.service包中以ServiceImpl為結尾的類下所有方法(引數任意)增強。
* test.service..*ServiceImpl.*(..):返回值任意且對est.service包和其子包中以ServiceImpl為結尾的類下所有方法(引數任意)增強。
然後配置<aspect>,其配置的主要目的是把通知織入切入點中,首先通過ref屬性引入配置好的通知類,然後通過三個引數確定要織入的物件和位置
aop:指定位置,有五個候選字
before:前置通知,目標方法執行之前呼叫
alter-Returning:後置通知(如果出現異常不會呼叫),在目標方法執行之後呼叫
around:環繞通知在目標方法之前和之後都呼叫
after-throwing:異常攔截通知,如果出現異常,就會呼叫
after:後置通知(無論是否出現 異常都會呼叫),在目標方法執行之後呼叫
method:選定要織入到切入點的通知類中的方法。(注:環繞通知的方法編寫時要確認環繞點)
pointcut-ref:選定切入點依賴物件,值為配置切入點時的id屬性。
這樣我們在獲取目標物件是,獲取到的就是Spring動態代理後進行增強過的代理物件。