AspectJ是一個基于Java語言的Aop框架佛舱。從Spring2.0 以后引入了AspectJ的支持样漆。目前的Spring框架出皇,建議開發(fā)者使用AspectJ實現(xiàn)Spring Aop 裆蒸。使用AspectJ實現(xiàn)Spring Aop的方式有兩種:一種是基于XML配置開發(fā)AspectJ分井,另一種是基于注解開發(fā)AspectJ。
基于XML配置開發(fā)AspectJ是指通過XML配置文件定義切面门躯、切入點及通知淆党,所有這些定義都必須在<aop:config>元素內(nèi)。
下面通過一個實例演示基于XML配置開發(fā)AspectJ的過程
目錄結(jié)構(gòu)
1.導(dǎo)入AspectJ框架相關(guān)的jar包
需要再像ch4應(yīng)用的/WEB-INF/lib目錄下導(dǎo)入jar包spring-aspect-5.0.2.RELEASE.jar和aspectjweaver-1.8.13.jar 生音。spring-aspect-5.0.2.RELEASE.jar是Spring為Aspect提供的實現(xiàn),Spring的包中已提供窒升。
aspectjweaver-1.8.13.jar是Aspect框架所提供的規(guī)范包
2.創(chuàng)建切面類
在ch4應(yīng)用的src目錄下缀遍,創(chuàng)建aspectj.xml包,在該包中創(chuàng)建切面類MyAspect饱须,并在類中編寫各種類型通知域醇。
MyAspect.java
package aspectj.xml;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/*
* 切面類,在次類中編寫各種類型通知
*/
public class MyAspect {
/**
* 前置通知,使用Joinpoint接口作為參數(shù)獲得目標(biāo)對象信息
*/
public void before(JoinPoint jp) {
System.out.println("前置通知:模擬權(quán)限控制");
System.out.println(".目標(biāo)對象:模擬權(quán)限控制" + jp.getTarget()
+ ".被增強處理的方法:" + jp.getSignature().getName());
}
/**
* 后置返回通知
*/
public void afterReturning(JoinPoint jp) {
System.out.println("后置返回通知:" + "模擬刪除臨時文件");
System.out.println(".被增強的處理方法" + jp.getSignature().getName());
}
/**
* 環(huán)繞通知
* ProceedingJoinPoint子接口譬挚,代表可以執(zhí)行的目標(biāo)方法
* 返回類型必須是Object
* 必須一個參數(shù)是ProceedingJoinPoint類型
* 必須是throws Throwable
*/
public Object around(ProceedingJoinPoint pjp) throws Throwable{
//開始
System.out.println("環(huán)繞開始:執(zhí)行目標(biāo)方法前锅铅,模擬開始事務(wù)");
//執(zhí)行當(dāng)前目標(biāo)方法
Object obj = pjp.proceed();
//結(jié)束
System.out.println("環(huán)繞結(jié)束:執(zhí)行目標(biāo)方法后,模擬關(guān)閉事務(wù)");
return obj;
}
/**
* 異常通知
*/
public void except(Throwable e) {
System.out.println("異常通知:" + "程序執(zhí)行異常" + e.getMessage());
}
/**
* 后置(最終)通知
*/
public void after() {
System.out.println("最終通知:模擬釋放資源");
}
}
3.創(chuàng)建配置文件减宣,并編寫相關(guān)配置
在aspect.xml包中盐须,創(chuàng)建配置文件applicationContext.xml,并在<aop:config>元素以及其子元素編寫相關(guān)配置
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 定義目標(biāo)對象(使用4.2.1節(jié)中的實現(xiàn)類) -->
<bean id="testDao" class="dynamic.jdk.TestDaoImpl"/>
<!-- 定義切面 -->
<bean id="myAspect" class="aspectj.xml.MyAspect"/>
<!-- AOP配置 -->
<aop:config>
<!-- 配置切面 -->
<aop:aspect ref="myAspect">
<!-- 配置切入點漆腌,通知增強哪些方法 -->
<aop:pointcut expression="execution(* dynamic.jdk.*.*(..))" id="myPointCut"/>
<!-- 將通知與切入點關(guān)聯(lián) -->
<!-- 關(guān)聯(lián)前置通知 -->
<aop:before method="before" pointcut-ref="myPointCut"/>
<!-- 關(guān)聯(lián)后置返回通知贼邓,在目標(biāo)方法成功執(zhí)行后執(zhí)行 -->
<aop:after-returning method="afterReturning" pointcut-ref="myPointCut"/>
<!-- 關(guān)聯(lián)環(huán)繞通知 -->
<aop:around method="around" pointcut-ref="myPointCut"/>
<!-- 關(guān)聯(lián)異常通知,沒有異常發(fā)生時將不會執(zhí)行增強闷尿,throwing屬性設(shè)置通知的第二個參數(shù)名稱 -->
<aop:after-throwing method="except" pointcut-ref="myPointCut" throwing="e"/>
<!-- 關(guān)聯(lián)后置(最終)塑径,不管目標(biāo)方法是否成功都要執(zhí)行 -->
<aop:after method="after" pointcut-ref="myPointCut"/>
</aop:aspect>
</aop:config>
</beans>
4.創(chuàng)建測試類
在aspectj.xml包中,創(chuàng)建測試類XMLAspectTest填具,在主方法中使用Spring容器獲取代理對象统舀,并執(zhí)行目標(biāo)方法。
XMLAspectTest.java
package aspectj.xml;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import dynamic.jdk.TestDao;
public class XMLAspectJTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext appCon = new ClassPathXmlApplicationContext("/aspectj/xml/applicationContext.xml");
//從容器中獲取增強后的目標(biāo)對象
TestDao testDaoAdvice = (TestDao)appCon.getBean("testDao");
//執(zhí)行方法
testDaoAdvice.save();
}
}
運行結(jié)果