Test类中的代码:
package com.jd.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jd.calculator.ICalculatorService;
public class Test {
public static void main(String[] args) {
//创建IOC容器并创建对象
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);
int result = calculatorService.mul(1, 1);
System.out.println("-->"+result);
}
}
在目标方法执行之前执行
@Before("execution(int mul(int, int))")
public void before(JoinPoint jp) {
Object target = jp.getTarget();
Object [] args = jp.getArgs();
String name = jp.getSignature().getName();
System.out.println(target.getClass().getName()+":The "+name+" method begins.");
System.out.println(target.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
}
运行结果:
com.jd.calculator.CalculatorService:The mul method begins.
com.jd.calculator.CalculatorService:Parameters of the mul method: [1,1]
-->1
在目标方法执行后执行,无论目标方法运行期间是否出现异常。注意:后置增强无法获取目标方法执行结果,可以在返回增强中获取
@After("execution(int mul(int, int))")
public void after(JoinPoint jp) {
Object target = jp.getTarget();
String name = jp.getSignature().getName();
System.out.println(target.getClass().getName()+":The "+name+" method ends.");
}
运行结果:
com.jd.calculator.CalculatorService:The mul method ends.
-->1
在目标方法正常结束后执行,可以获取目标方法的执行结果
@AfterReturning(value="execution(int mul(int, int))",returning="result")
public void afterReturning(JoinPoint jp,Object result) {
Object target = jp.getTarget();
String name = jp.getSignature().getName();
System.out.println(target.getClass().getName()+":Result of the "+name+" method:"+result);
}
运行结果:
com.jd.calculator.CalculatorService:Result of the mul method:1
-->1
目标方法抛出异常之后执行,可以访问到异常对象,且可以指定在出现哪种异常时才执行增强代码
@AfterThrowing(value="execution(int mul(int, int))",throwing="ex")
public void afterThrowing(JoinPoint jp,ArithmeticException ex) {
Object target = jp.getTarget();
String name = jp.getSignature().getName();
System.out.println(target.getClass().getName()+":The "+name+" method had an exception."+ex.getMessage());
}
让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==1) {
throw new RuntimeException("两数之积不能为1");
}
return result;
}
目标方法执行前后都可以织入增强处理
@Around("execution(int mul(..))")
public Object around(ProceedingJoinPoint jp) {
Object target = jp.getTarget();
Object [] args = jp.getArgs();
String name = jp.getClass().getName();
Object result = null;
try {
try {
//前置增强
System.out.println(target.getClass().getName()+":The "+name+" method begins.");
System.out.println(target.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
result = jp.proceed();
}finally{
//后置增强
System.out.println(target.getClass().getName()+":The "+name+" method ends.");
}
//返回增强
System.out.println(target.getClass().getName()+":Result of the "+name+" method:"+result);
} catch (Throwable e) {
//异常增强
System.out.println(target.getClass().getName()+":The "+name+" method had an exception."+e.getMessage());
e.printStackTrace();
}
return result;
出异常时的结果:
com.sun.proxy.$Proxy8
com.jd.calculator.CalculatorService:The org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint method begins.
com.jd.calculator.CalculatorService:Parameters of the org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint method: [1,1]
com.jd.calculator.CalculatorService:The org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint method ends.
com.jd.calculator.CalculatorService:The org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint method had an exception.两数之积不能为1
java.lang.RuntimeException: 两数之积不能为1
不出异常时的结果:
com.sun.proxy.$Proxy8
com.jd.calculator.CalculatorService:The org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint method begins.
com.jd.calculator.CalculatorService:Parameters of the org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint method: [1,1]
com.jd.calculator.CalculatorService:The org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint method ends.
com.jd.calculator.CalculatorService:Result of the org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint method:1
-->1
@Around中可以实现@Before、@AfterRunning、@AfterThrowing、@After中任意一种或多种
try {
try {
doBefore();// @Before注解所修饰的方法
method.invoke();// 执行目标对象内的方法
} finally {
doAfter();// @After注解所修饰的方法
}
doAfterReturning();// @AfterReturning注解所修饰的方法
} catch (Exception e) {
doAfterThrowing();// @AfterThrowing注解所修饰的方法
}
由上图或@Around(环绕增强)的代码分析可知:先执行前置增强——>再调用目标方法
——>再执行后置增强——>最后执行返回增强(不报异常时)或执行异常增强(报异常时)
//前置增强
@Before("execution(int mul(int, int))")
public void before(JoinPoint jp) {
Object target = jp.getTarget();
Object [] args = jp.getArgs();
String name = jp.getSignature().getName();
System.out.println(target.getClass().getName()+":The "+name+" method begins.");
System.out.println(target.getClass().getName()+":Parameters of the "+name+" method: ["+args[0]+","+args[1]+"]");
}
//返回增强
@AfterReturning(value="execution(int mul(int, int))",returning="result")
public void afterReturning(JoinPoint jp,Object result) {
Object target = jp.getTarget();
String name = jp.getSignature().getName();
System.out.println(target.getClass().getName()+":Result of the "+name+" method:"+result);
}
//后置增强
@After("execution(int mul(int, int))")
public void after(JoinPoint jp) {
Object target = jp.getTarget();
String name = jp.getSignature().getName();
System.out.println(target.getClass().getName()+":The "+name+" method ends.");
}
//异常增强(又称异常通知)
@AfterThrowing(value="execution(int mul(int, int))",throwing="ex")
public void afterThrowing(JoinPoint jp,Exception ex) {
Object target = jp.getTarget();
String name = jp.getSignature().getName();
System.out.println(target.getClass().getName()+":The "+name+" method had an exception."+ex.getMessage());
}
@Override
public int mul(int a, int b) {
int result = a*b;
if(result==1) {
throw new RuntimeException("两数之积不能为1");
}
return result;
}
@AfterThrowing(value="execution(int mul(int, int))",throwing="ex")
public void afterThrowing(JoinPoint jp,Exception ex) {
Object target = jp.getTarget();
String name = jp.getSignature().getName();
System.out.println(target.getClass().getName()+":The "+name+" method had an exception."+ex.getMessage());
}
@AfterThrowing(value="execution(int mul(int, int))",throwing="ex")
public void afterThrowing(JoinPoint jp,NullPointerException ex) {
Object target = jp.getTarget();
String name = jp.getSignature().getName();
System.out.println(target.getClass().getName()+":The "+name+" method had an exception."+ex.getMessage());
}
①@Before、@After、@AfterRunning和@AfterThrowing修饰的方法可以通过声明JoinPoint 类型参数变量获取目标方法的信息;@Around修饰的方法必须声明ProceedingJoinPoint类型的参数获取目标方法的信息
②@Before、@After、@AfterRunning和@AfterThrowing修饰的方法没有返回值;而@Around修饰的方法必须有返回值,返回值为目标方法的返回值