目录
AspectJ一共支持5种类型的增强注解,@Before前置增强、@After后置增强、@AfterReturning返回增强、@AfterThrowing异常增强和@Around环绕增强
前置增强
@Before:前置增强,在目标方法执行之前执行
@Before(value="execution(int mul(int ,int ))")
public void before(JoinPoint jp) {
Object obj=jp.getTarget();
Object [] args=jp.getArgs();
String name=jp.getSignature().getName();
System.out.println(obj.getClass().getName()+":The "+name+" method begins.");
System.out.println(obj.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
}
- Object obj=jp.getTarget():获取目标对象
- Object [] args=jp.getArgs():获取匹配方法的参数
- String name=jp.getSignature().getName():获取匹配方法的方法名
后置增强
@After:后置增强,在目标方法执行后执行,无论目标方法运行期间是否出现异常,该增强注释的方法均会执行。注意:后置增强无法获取目标方法执行结果,可以在返回增强中获取
@After("value="execution(int mul(..))"")
public void after(JoinPoint jp) {
Object obj=jp.getTarget();
String name=jp.getSignature().getName();
System.out.println(obj.getClass().getName()+":The "+name+" method ends.");
}
返回增强
@AfterReturning:返回增强,在目标方法正常结束后执行,可以获取目标方法的执行结果,如果目标方法运行异常则不执行
@AfterReturning(value="execution(int mul(..))",returning="a")
public void afterReturning(JoinPoint jp,Object a) {
Object obj=jp.getTarget();
String name=jp.getSignature().getName();
System.out.println(obj.getClass().getName()+":Result of the "+name+" method:"+a);
}
注意:returning=“a”表示目标方法的返回值返回到a中,注意afterReturning方法中的Object类参数名要与returning值一致
异常增强
@AfterThrowing:异常增强,在目标方法运行期间出现异常时执行,否则不执行
@AfterThrowing(value="execution(int mul(..))",throwing="e")
public void afterThrowing(JoinPoint jp,RuntimeException e) {//此时的异常类必需为抛出异常的父类或相同异常,即此处的异常>=抛出的异常
Object obj=jp.getTarget();
String name=jp.getSignature().getName();
System.out.println(obj.getClass().getName()+":The "+name+" method has a exception:"+e.getMessage());
}
注意:throwing=“e”用于接受目标方法抛出的异常,注意afterThrowing方法中的第二个参数名要与throwing的值一致,且第二个参数的异常类型要是目标方法抛出异常的父类或同类,否则出错
前四种增强的执行过程及顺序
try {
try {
//@Before注解所修饰的方法
//执行目标对象内的方法
}finally {
//@After注解所修饰的方法
}
//@AfterReturning注解所修饰的方法
} catch (Throwable e) {
//@AfterThrowing注解所修饰的方法
}
执行结果:
//正常
com.jd.calculator.CalculatorService:The mul method begins.
com.jd.calculator.CalculatorService:Parameters of the mul method: [1,1]
com.jd.calculator.CalculatorService:The mul method ends.
com.jd.calculator.CalculatorService:Result of the mul method:1
-->1
//异常
com.jd.calculator.CalculatorService:The mul method begins.
com.jd.calculator.CalculatorService:Parameters of the mul method: [0,1]
com.jd.calculator.CalculatorService:The mul method ends.
com.jd.calculator.CalculatorService:The mul method has a exception:结果不能为0
执行顺序分析如下:
①前置增强--->目标方法--->目标方法出现异常--->finally中的后置增强--->catch中的异常增强
②前置增强--->目标方法--->目标方法不出现异常--->finally中的后置增强--->返回增强
环绕增强
@Around:环绕增强,在@Around修饰的方法中可以实现@Before,@After,@AfterReturning和@AfterThrowing的增强效果,可以实现动态代理的全过程,代码如下:
@Around(value="execution(int *(..))")
public Object around(ProceedingJoinPoint jp) {
Object result=null;
Object obj=jp.getTarget();
Object [] args=jp.getArgs();
String name=jp.getSignature().getName();
try {
try {
//前置增强
System.out.println(obj.getClass().getName()+":The "+name+" method begins.");
System.out.println(obj.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
//目标方法
result=jp.proceed();
} finally {
//后置增强
System.out.println(obj.getClass().getName()+":The "+name+" method ends.");
}
//返回增强
System.out.println(obj.getClass().getName()+":Result of the "+name+" method:"+result);
} catch (Throwable e) {
//异常增强
System.out.println(obj.getClass().getName()+":The "+name+" method has a exception:"+e.getMessage());
}
return result;
}
和如下代码等效:
//前置增强
@Before(value="execution(int mul(..))")
public void before(JoinPoint jp) {
Object obj=jp.getTarget();
Object [] args=jp.getArgs();
String name=jp.getSignature().getName();
System.out.println(obj.getClass().getName()+":The "+name+" method begins.");
System.out.println(obj.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 obj=jp.getTarget();
String name=jp.getSignature().getName();
System.out.println(obj.getClass().getName()+":Result of the "+name+" method:"+a);
}
//后置增强
@After(value="execution(int mul(..))")
public void after(JoinPoint jp) {
Object obj=jp.getTarget();
String name=jp.getSignature().getName();
System.out.println(obj.getClass().getName()+":The "+name+" method ends.");
}
//异常增强
@AfterThrowing(value="execution(int mul(..))",throwing="e")
public void afterThrowing(JoinPoint jp,RuntimeException e) {//此时的异常类必需为抛出异常的父类或相同异常,即此处的异常>=抛出的异常
Object obj=jp.getTarget();
String name=jp.getSignature().getName();
System.out.println(obj.getClass().getName()+":The "+name+" method has a exception:"+e.getMessage());
}
运行结果:
com.jd.calculator.CalculatorService:The mul method begins.
com.jd.calculator.CalculatorService:Parameters of the mul method: [1,1]
com.jd.calculator.CalculatorService:The mul method ends.
com.jd.calculator.CalculatorService:Result of the mul method:1
-->1
注意:1、前四种增强修饰的方法可以通过声明JoinPoint 类型参数变量获取目标方法的信息(方法名、参数列表等信息);@Around修饰的方法必须声明ProceedingJoinPoint类型的参数,该变量可以决定是否执行目标方法,jp.proceed()表示执行目标方法
2、前四种增强修饰的方法没有返回值(即为void);而@Around修饰的方法必须有返回值,返回值为目标方法的返回值;