AspectJ中5种类型的增强注解的区别
文章目录
一、如何定义五种增强注解?
二、五种增强注解的区别
一、如何定义五种增强注解?
前置增强,后置增强,返回增强,异常增强如定义如以下代码所示:
package com.jd.calculator;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect("")
public class CalculatorAspect {
@Before("execution( int mul(..))") //前置注解,在目标方法执行之前执行
public void before(JoinPoint jp) {
Object object = jp.getTarget();
Object [] args =jp.getArgs();
String name = jp.getSignature().getName();
System.out.println(object.getClass().getName()+":The "+name+" method begins.");
System.out.println(object.getClass().getName()+":Parameters of the "+name+" method: ["+ args[0]+","+args[1]+"]");
}
@AfterReturning(value="execution( int mul(..))",returning="a")
//返回注解,如果目标方法不出现异常,则在执行完后置注解后,执行该注解,且异常注解不执行
public void afterReturning(JoinPoint jp,Object a) {
Object object = jp.getTarget();
Object [] args =jp.getArgs();
String name = jp.getSignature().getName();
System.out.println(this.getClass().getName()+":Result of the "+name+" method:"+a);
}
@After("execution( int mul(..))") //后置注解,在目标方法执行后执行,无论目标方法是否发生异常,都一定会执行
public void after(JoinPoint jp) {
Object object = jp.getTarget();
Object [] args =jp.getArgs();
String name = jp.getSignature().getName();
System.out.println(this.getClass().getName()+":The "+name+" method ends.");
}
@AfterThrowing(value="execution( int mul(..))",throwing="ex") //目标方法发生异常才执行该注解
public void afterThrowing(JoinPoint jp,Exception ex) {
Object object = jp.getTarget();
Object [] args =jp.getArgs();
String name = jp.getSignature().getName();
System.out.println(this.getClass().getName()+":The "+name+" method had a exception"+ex);
}
}
环绕增强定义
package com.jd.calculator;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Component
@Aspect("")
public class CalculatorAspect {
@Around(value="execution( int mul(..))")
public Object around(ProceedingJoinPoint jp) {
Object a=null;
Object object = jp.getTarget();
Object [] args =jp.getArgs();
String name = jp.getSignature().getName();
try {
try {
//前置增强
System.out.println(object.getClass().getName()+":The "+name+" method begins.");
System.out.println(object.getClass().getName()+":Parameters of the "+name+" method: ["+ args[0]+","+args[1]+"]");
a=jp.proceed();
} finally {
//后置增强
System.out.println(this.getClass().getName()+":The "+name+" method ends.");
}
//返回增强
System.out.println(this.getClass().getName()+":Result of the "+name+" method:"+a);
} catch (Throwable e) {
异常增强
System.out.println(this.getClass().getName()+":The "+name+" method had a exception"+e);
}
return a;
}
}
二、五种增强的区别
1、执行顺序方面:前置增强——>后置增强——>如果目标方法不发生异常执行返回增强,否则执行异常增强,执行顺序如一下代码所示
try {
try {
//前置增强
System.out.println(object.getClass().getName()+":The "+name+" method begins.");
System.out.println(object.getClass().getName()+":Parameters of the "+name+" method: ["+ args[0]+","+args[1]+"]");
a=jp.proceed();
} finally {
//后置增强
System.out.println(this.getClass().getName()+":The "+name+" method ends.");
}
//返回增强
System.out.println(this.getClass().getName()+":Result of the "+name+" method:"+a);
} catch (Throwable e) {
//异常增强
System.out.println(this.getClass().getName()+":The "+name+" method had a exception"+e);
}
举例说明
在 CalculatorService中定义如下异常
package com.jd.calculator;
import org.springframework.stereotype.Service;
@Service
public class CalculatorService implements ICalculatorService {
@Override
public int mul(int a, int b) {
int result = a*b;
if(result==0) {
throw new RuntimeException("两数之积不能为零");
}
return result;
}
测试类代码如下:
Test类中,传参,使a,b都为零,故意使目标方法爆发异常,此时不会执行返回增强
Test类中,传参,使a,b都为零目标方法不爆发异常,执行结果如下所示,验证了执行顺序的正确性
2、使用类方面:环绕增强如以上定义的所示,它包含了以上四种增强,使用的是ProceedingJoinPoint类,它是JoinPoint的子类,另外四种增强使用的是JoinPoint类