除了使用xml配置外,還可以使用注解的方式實現上述幾種通知。
LogAspectAnnotation.java:
package aop.Aspe; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Component("logAnn") @Aspect public class LogAspectAnnotation { @Before("execution(public * springProject.Student.add(..))") public void bBefore() { System.out.println("@@@前置通知"); } @AfterReturning("execution(public * springProject.Student.add(..))") public void bAfter() { System.out.println("@@@后置通知"); } @AfterThrowing("execution(public * springProject.Student.add(..))") public void bThrowing() { System.out.println("@@@異常通知"); } //環繞通知 ,參數ProceedingJoinPoint @Around("execution(public * springProject.Student.add(..))") public void myAround(ProceedingJoinPoint jp ) { //方法之前:前置通知 System.out.println("《【環繞】方法之前:前置通知"); try { //方法執行時 jp.proceed() ;//執行方法 //方法之前之后:后置通知 System.out.println("《【環繞】方法之前之后:后置通知"); }catch(Throwable e) { //發生異常時:異常通知 System.out.println("《【環繞】發生異常時:異常通知"); }finally { //最終通知 System.out.println("《【環繞】最終通知"); } } }
tips:
@Component("logAnn"): 把這個類加入ioc容器,id為logAnn。
必須在xml中,加入xmlns:context="http://www.springframework.org/schema/context"
然后調用掃描器:<context:component-scan base-package="aop.Aspe"></context:component-scan>
掃描器 會將 指定的包 中的 @Componet @Service @Respository @Controller修飾的類產生的對象 增加到IOC容器中
@Aspect: 聲明這個類是個通知。
不需要通過掃描器,只需要在xml文件中開啟即可:<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Before("execution(public * springProject.Student.add(..))"):
聲明這個方法是個前置通知,關聯的業務方法為add。
@AfterReturning("execution(public * springProject.Student.add(..))")
聲明這個方法是個前置通知,關聯的業務方法為add。
@AfterThrowing("execution(public * springProject.Student.add(..))")
聲明這個方法是個異常通知。
@Around("execution(public * springProject.Student.add(..))")
聲明這個方法為環繞通知。
上述各個通知對應的方法名可以隨便取。
如果想要獲取目標對象的一些參數,則需要使用一個對象:JointPoint。
package org.lanqiao.aop; import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; //<bean id="logAnnotation" class="org.lanqiao.aop.LogAspectAnnotation"> //@Component("logAnnotation") //將LogAspectAnnotation納入springIOC容器中 @Aspect //此類是一個通知 public class LogAspectAnnotation { //前置通知 @Before("execution(public * addStudent(..))") //屬性:定義切點 public void myBefore(JoinPoint jp) { System.out.println("《注解形式-前置通知》:目標對象:"+jp.getTarget()+",方法名:"+jp.getSignature().getName() +",參數列表:"+ jp.getArgs().length ); } //后置通知 @AfterReturning( pointcut= "execution(public * addStudent(..))" ,returning="returningValue" ) public void myAfter(JoinPoint jp,Object returningValue) {//returningValue是返回值,但需要告訴spring System.out.println("《注解形式-后置通知》:目標對象:"+jp.getTarget()+",方法名:"+jp.getSignature().getName() +",參數列表:"+ jp.getArgs().length+",返回值:"+returningValue ); } /*環繞通知 ,參數ProceedingJoinPoint @Around("execution(public * addStudent(..))") public void myAround(ProceedingJoinPoint jp ) { //方法之前:前置通知 System.out.println("《【環繞】方法之前:前置通知"); try { //方法執行時 jp.proceed() ;//執行方法 //方法之前之后:后置通知 System.out.println("《【環繞】方法之前之后:后置通知"); }catch(Throwable e) { //發生異常時:異常通知 System.out.println("《【環繞】發生異常時:異常通知"); }finally { //最終通知 System.out.println("《【環繞】最終通知"); } }*/ //異常通知:如果只捕獲特定類型的已存銀行,則可以通過第二個參數實現:e @AfterThrowing(pointcut= "execution(public * addStudent(..))",throwing="e") public void myException(JoinPoint pj, NullPointerException e) {//此異常通知 只會捕獲NullPointerException類型的異常 System.out.println("&&&&&&《注解形式-異常通知》----e:"+e.getMessage()); } //最終通知 @After("execution(public * addStudent(..))") public void myAfter() { System.out.println("《[myAfter]注解形式-最終通知-----通知》----"); } }
注解形式的返回值:
a.聲明返回值 的參數名:
@AfterReturning( pointcut= "execution(public * addStudent(..))" ,returning="returningValue" ) public void myAfter(JoinPoint jp,Object returningValue) {//returningValue是返回值,但需要告訴spring System.out.println("返回值:"+returningValue );
b: 注解形式實現aop時,通知的方法的參數不能多、少。
c: 實現接口形式、注解形式 只捕獲聲明的特定類型的異常,而其他類型異常不捕獲。
d: 異常通知,可以只在某個特定異常才輸出。
@AfterThrowing(pointcut= "execution(public * addStudent(..))",throwing="e") public void myException(JoinPoint pj, NullPointerException e) {//此異常通知 只會捕獲NullPointerException類型的異常 System.out.println("&&&&&&《注解形式-異常通知》----e:"+e.getMessage()); }