基於註解開發AspectJ要比基於XML配置開發AspectJ便捷許多,因此在實際開發中推薦使用註解方式。關於註解的相關內容以下:spring
在通知中使用value屬性定義切入點,經過execution函數,能夠定義切入點的方法切入。
語法:execution(<訪問修飾符>?<返回類型><方法名>(<參數>)<異常>)
例如:express
添加依賴app
<!-- AOP聯盟依賴 --> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--aspectJ相關依賴--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.0.2.RELEASE</version> </dependency>
建立StuDao類ide
public class StuDao { public void save(){ System.out.println("保存"); } public String modify(){ System.out.println("修改"); return "modify..."; } public void delete(){ System.out.println("刪除"); } public void findOne(){ System.out.println("查詢單條信息"); int i = 1/0; } public void findAll(){ System.out.println("查詢全部信息"); } }
建立切面類函數
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; @Aspect public class MyAspectAnno { /** * 前置通知 * @param joinPoint 用於獲取切點信息 */ @Before(value = "execution(* com.aspectj.demo.StuDao.save(..))") public void before(JoinPoint joinPoint){ System.out.println("前置通知============="+joinPoint); } /** * 後置返回通知,經過returning屬性能夠定義方法返回值,做爲參數 * @param result 和returning屬性的值保持一致 */ @AfterReturning(value = "execution(* com.aspectj.demo.StuDao.modify(..))",returning = "result") public void afterReturing(Object result){ System.out.println("後置返回通知=========="+result); } /** * 環繞通知 * 若是不調用ProceedingJoinPoint的proceed方法,那麼目標方法就被攔截了 * @param joinPoint 能夠調用攔截目標方法執行 * @return 目標代理方法執行返回值 * @throws Throwable */ @Around(value = "execution(* com.aspectj.demo.StuDao.delete(..))") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("環繞前置通知*************"); Object obj = joinPoint.proceed(); System.out.println("環繞後置通知*************"); return obj; } //異常通知 @AfterThrowing(value = "execution(* com.aspectj.demo.StuDao.findOne(..))",throwing = "e") public void afterThrowing(Throwable e){ System.out.println("異常通知================"+e); } //最終通知,不管是否出現異常,最終通知老是會被執行的 @After(value = "execution(* com.aspectj.demo.StuDao.findAll(..))") public void after(){ System.out.println("最終通知=================="); } }
配置applicationContext.xml文件測試
<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"> <!--開啓AspectJ的註解開發,自動代理--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <bean id="stuDao" class="com.aspectj.demo.StuDao"></bean> <bean class="com.aspectj.demo.MyAspectAnno"></bean> </beans>
建立測試類spa
@Test public void demo(){ ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); StuDao stuDao = (StuDao) app.getBean("stuDao"); stuDao.save(); stuDao.modify(); stuDao.delete(); stuDao.findAll(); stuDao.findOne(); }
運行結果代理
在每一個通知內定義切點,會形成工做量大,不易維護,對於重複的切點,可使用@Pointcut進行定義。
切點方法:private void 無參數方法,方法名爲切點名,當通知多個切點時,可使用||進行鏈接。
把切面類代碼修改成:code
@Aspect public class MyAspectAnno { //前置通知 @Before(value = "myPointcut1()") public void before(JoinPoint joinPoint){ System.out.println("前置通知============="+joinPoint); } //後置通知 @AfterReturning(value = "myPointcut2()",returning = "result") public void afterReturing(Object result){ System.out.println("後置返回通知=========="+result); } //環繞通知 @Around(value = "myPointcut3()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("環繞前置通知*************"); Object obj = joinPoint.proceed(); System.out.println("環繞後置通知*************"); return obj; } //異常通知 @AfterThrowing(value = "myPointcut4()",throwing = "e") public void afterThrowing(Throwable e){ System.out.println("異常通知================"+e); } //最終通知 @After(value = "myPointcut5()") public void after(){ System.out.println("最終通知=================="); } @Pointcut(value = "execution(* com.aspectj.demo.StuDao.save(..))") private void myPointcut1(){} @Pointcut(value = "execution(* com.aspectj.demo.StuDao.modify(..))") private void myPointcut2(){} @Pointcut(value = "execution(* com.aspectj.demo.StuDao.delete(..))") private void myPointcut3(){} @Pointcut(value = "execution(* com.aspectj.demo.StuDao.findOne(..))") private void myPointcut4(){} @Pointcut(value = "execution(* com.aspectj.demo.StuDao.findAll(..))") private void myPointcut5(){} }
添加依賴xml
<!-- AOP聯盟依賴 --> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--aspectJ相關依賴--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.0.2.RELEASE</version> </dependency>
建立StuDao接口和實現類StuDaoImpl
StuDao接口
public interface StuDao { public void save(); public void delete(); public String modify(); public void findOne(); public void findAll(); }
StuDaoImpl實現類
public class StuDaoImpl implements StuDao { @Override public void save() { System.out.println("保存"); } @Override public String modify() { System.out.println("修改"); return "modify..."; } @Override public void delete() { System.out.println("刪除"); } @Override public void findOne() { System.out.println("查詢單條記錄"); int i = 1/0; } @Override public void findAll() { System.out.println("查詢全部記錄"); } }
建立切面類
public class MyAspectjXml { //前置通知 public void before(){ System.out.println("前置通知==============="); } //後置返回通知 public void afterReturing(Object result){ System.out.println("後置返回通知============="+result); } //環繞通知 public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("環繞前置通知**************"); Object obj = joinPoint.proceed(); System.out.println("環繞後置通知**************"); return obj; } //異常通知 public void afterThrowing(Throwable e){ System.out.println("異常通知=================="+e); } //最終通知 public void after(){ System.out.println("最終通知==================="); } }
配置applicationContext.xml文件
<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"> <!--配置目標類--> <bean id="stuDao" class="com.aspectj.demo2.StuDaoImpl"></bean> <!--配置切面類--> <bean id="myAspectjXml" class="com.aspectj.demo2.MyAspectjXml"></bean> <!--AOP相關配置--> <aop:config> <!--配置切入點--> <aop:pointcut id="pointcut1" expression="execution(* com.aspectj.demo2.StuDao.save(..))"></aop:pointcut> <aop:pointcut id="pointcut2" expression="execution(* com.aspectj.demo2.StuDao.modify(..))"></aop:pointcut> <aop:pointcut id="pointcut3" expression="execution(* com.aspectj.demo2.StuDao.delete(..))"></aop:pointcut> <aop:pointcut id="pointcut4" expression="execution(* com.aspectj.demo2.StuDao.findOne(..))"></aop:pointcut> <aop:pointcut id="pointcut5" expression="execution(* com.aspectj.demo2.StuDao.findAll(..))"></aop:pointcut> <!--配置AOP的切面--> <aop:aspect ref="myAspectjXml"> <!--配置前置通知--> <aop:before method="before" pointcut-ref="pointcut1"></aop:before> <!--配置後置返回通知--> <aop:after-returning method="afterReturing" pointcut-ref="pointcut2" returning="result"></aop:after-returning> <!--配置環繞通知--> <aop:around method="around" pointcut-ref="pointcut3"></aop:around> <!--配置異常通知--> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="e"></aop:after-throwing> <!--配置最終通知--> <aop:after method="after" pointcut-ref="pointcut5"></aop:after> </aop:aspect> </aop:config> </beans>
建立測試類
@Test public void demo(){ ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); StuDao stuDao = (StuDao) app.getBean("stuDao"); stuDao.save(); stuDao.delete(); stuDao.modify(); stuDao.findAll(); stuDao.findOne(); }
運行結果