在前一篇配置Spring Aop的博客中提到过两种增强方法:before(JoinPoint jd)和
after(JoinPoint jd)
下面具体介绍五种增强方法,代码如下:
@Aspect
@Component
public class Calculator {
//前置增强
@Before("execution(int mul(int, int))")
public void before(JoinPoint jd) {
Object obj = jd.getTarget();
Object [] args = jd.getArgs();
String name = jd.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(int,int))",returning = "result")
public void after(JoinPoint jd,Object result) {
Object obj = jd.getTarget();
String name = jd.getSignature().getName();
System.out.println(obj.getClass().getName()+":Result of the "+name+" method:"+result);
}
//后置增强
@After("execution(int mul(int, int))")
public void after(JoinPoint jd) {
Object obj = jd.getTarget();
String name = jd.getSignature().getName();
System.out.println(obj.getClass().getName()+":The "+name+" method ends.");
}
//异常增强
@AfterThrowing(value = "execution(int mul(int,int))",throwing = "ex")
public void after(JoinPoint jd,RuntimeException ex) {
Object obj = jd.getTarget();
String name = jd.getSignature().getName();
System.out.println(obj.getClass().getName()+":The "+name+" have a expection: "+ ex.getMessage());
}
}
有了这四种增强方法,代码会如下执行:
①、执行前置增强;②、执行目标对象的mul方法;③、执行后置增强;④、执行返回增强;⑤、如果前面方法出现异常,则执行异常增强;
可以看到前四种增强方法是对目标对象的mul方法的补充
注意:返回增强后于后置增强执行;
运行结果:
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
修改目标类CalculatorService中的mul方法,使其抛出运行时异常:
@Service
public class CalculatorService implements ICalculatorService {
@Override
public int mul(int a, int b) {
int result = a*b;
if (result==1) {
throw new RuntimeException("抛出运行时异常!");
}
return result;
}
@Override
public int div(int a, int b) {
System.out.println(this.getClass().getName()+":The div method begins.");
System.out.println(this.getClass().getName()+":Parameters of the div method: ["+a+","+b+"]");
int result = a/b;
System.out.println(this.getClass().getName()+":Result of the div method:"+result);
System.out.println(this.getClass().getName()+":The div method ends.");
return result;
}
}
当程序运行并出现运行时异常时,Calculator类中的定义的异常增强方法就会捕获到异常信息并输出:
注意:异常增强中public void after(JoinPoint jd,RuntimeExceptionex ex) {
此处定义的异常级别要高于或同与要抛出的异常级别;
Exception in thread "main" 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:The mul have a expection: 抛出运行时异常!
java.lang.RuntimeException: 抛出运行时异常!
at com.jd.calculator.CalculatorService.mul(CalculatorService.java:13)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
...
下面介绍第五种增强方法:环绕增强
@Around("execution(int mul(int, int))")
public Object around(ProceedingJoinPoint jp) {
Object result=null;
Object target = jp.getTarget();
String methodName = target.getClass().getName();
Object [] args = jp.getArgs();
try {
try {
//前置增强
System.out.println(target.getClass().getName()+":The "+methodName+" method begins.");
System.out.println(target.getClass().getName()+":Parameters of the "+methodName+" method: ["+args[0]+","+args[1]+"]");
result = jp.proceed();
} finally {
//后置增强
System.out.println(target.getClass().getName()+":The "+methodName+" method ends.");
}
//返回增强
System.out.println(target.getClass().getName()+":Result of the "+methodName+" method:"+result);
} catch (Throwable e) {
//异常增强
System.out.println(target.getClass().getName()+":The "+methodName+" have a expection: "+ e.getMessage());
e.printStackTrace();
}
return result;
}
输出结果:
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
可以看到:
环绕增强的方法可以实现@Before,@After,@AfterReturning和@AfterThrowing增强效果,实现了动态代理全过程;
注意:前四种增强修饰的方法没有返回值;而@Around修饰的方法必须有返回值,返回值为目标方法的返回值;前四种增强方法中的参数为JoinPoint类型,而环绕增强方法中的参数为ProceedingJoinPoint 类型;