除了基于@aspectj注解的形式來實作aop外,我們還可以在ioc容器中配置。先來看看一個常見的應用場景,在我們的web項目中,我們需要為service層配置事務,傳統的做法是在每個業務邏輯方法重複下面配置中:
created with raphaël 2.1.0程式開始1. 擷取dao層封裝好的資料庫查詢api,如hibernate中的sessionfactory/session和mybatis中的xxxmapper2. 開啟事務3. 根據入參查詢資料庫完成相應的業務邏輯操作4. 關閉事務5. 如果有必要則關閉連接配接。程式結束
第1步可以通過我們springioc注入完成,但2,4步很多時候則顯得非常冗雜,我們需要在每個方法中都開啟關閉事務,于是我們利用aop的橫切邏輯來實作事務配置:
以上執行個體就是我們基于schema的方式來配置切面,這樣,我們com.yc.service包下,以impl結尾的類中所有的方法都會根據方法名織入相應的事務,就不用之前繁瑣地寫死式為每個方法配置事務了。
下面我們通過一個比較全面的例子來認識schema特色配置
控制台列印資訊: myadvice 實施@before,目标對象方法入參為:zenghao myadvice 實施around前,目标對象方法入參為:zenghao i’m zenghao ,i’m logining myadvice 實施around後,目标對象方法入參為:zenghao myadvice 實施after,目标對象方法入參為:zenghao myadvice 實施afterreturning,目标對象方法傳回值為:null myadvice 實施afterthrowing,目标對象方法抛出異常:illegal logout exception in thread “main” java.lang.runtimeexception: illegal logout at test.aop3.usercontroller.logout(usercontroller.java:10) at test.aop3.usercontroller$$fastclassbyspringcglib$$d89843a8.invoke() ……(忽略下面異常資訊)……
結合上面執行個體,我們分析:
<code>1. aop切點、切面等配置必須被<aop:config>标簽包括 2. 一個<aop:config>可以配置多個切點、切面,一個切面可以配置多個增強 3. <aop:pointcut>可以配置在<aop:config>和<aop:aspect>中,配置在<aop:config>中對所 有<aop:aspect>可見,配置在特定的<aop:aspect>則對其他的<aop:aspect>不可見。 4. 在<aop:config>中,各标簽配置順序先後依序必須為:<aop:pointcut>、<aop:advisor>、<aop:aspect>,若<aop:pointcut>配置在<aop:aspect>中,則無順序要求(即在<aop:after>等标簽前後都可以,即使<aop:after>标簽中引用了該<aop:pointcut>标簽) 5. 在xml檔案中使用邏輯運算符&&會報錯,必須使用and,||和!則無此限制</code>
在前面的例子中,我們沒有提到引介增強,實際上,引介增強的配置和其他增強的差異是挺大的,它沒有了method,pointcut,pointcut-ref屬性,但多了以下四個屬性:
1. implement-interface
2. default-impl
3. implement-interface
4. delegate-ref
前面我們在談等幾個标簽的配置順序中提到,它的使用格式為:
<code><aop:advisor advice-ref="實作了特定的增強接口的增強類" order="1" pointcut="使用切點表達式函數定義切點"/></code>