除前置通知(Before)外,AOP 里面还有返回通知(AfterReturning)、异常通知(AfterThrowing)、后置通知(After)和环绕通知(Around)。
一、返回通知
切面类:
package com.spring.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
@EnableAspectJAutoProxy
@Aspect
@Component
public class LogAspect {
@AfterReturning(value = "execution(* com.spring.aop.Calculator.*(..))",returning = "result")
public void afterReturningMethod(JoinPoint joinPoint, Object result){
System.out.println(result);
}
}
返回通知相较于前置通知,在 @AfterReturning 注解中增加了 returning 属性,该属性的属性值与 afterReturningMethod 的形参名称保持一致。当目标方法有返回值时,可用于接收目标方法的返回值。
二、异常通知
切面类:
package com.spring.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
@EnableAspectJAutoProxy
@Aspect
@Component
public class LogAspect {
@AfterThrowing(value = "execution(* com.spring.aop.Calculator.*(..))",throwing = "ex")
public void afterThrowingMethod(JoinPoint joinPoint, Throwable ex){
System.out.println(ex);
}
}
异常方法用于当目标方法出现异常时调用,特点是在 @AfterThrowing 注解中增加了 throwing 属性,其属性值与 afterThrowingMethod 方法的形参名称保持一致,用以接收目标方法的异常信息。
三、后置通知
切面类:
package com.spring.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
@EnableAspectJAutoProxy
@Aspect
@Component
public class LogAspect {
@After(value = "execution(* com.spring.aop.Calculator.*(..))")
public void afterThrowingMethod(){
System.out.println("after method");
}
}
后置通知与前置通知类似。
四、获取目标方法的名称及参数:
切面类:
package com.spring.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@EnableAspectJAutoProxy
@Aspect
@Component
public class LogAspect {
@Before(value = "execution(* com.spring.aop.Calculator.*(..))")
public void beforeMethod(JoinPoint joinPoint){
//获取目标方法名称
System.out.println(joinPoint.getSignature().getName());
//获取目标方法参数
System.out.println(Arrays.toString(joinPoint.getArgs()));
}
}
五、环绕通知
环绕通知等于是将以上四种通知在 try…catch…finally… 里面进行布置。
切面类:
package com.spring.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
@EnableAspectJAutoProxy
@Aspect
@Component
public class LogAspect {
@Around(value = "execution(* com.spring.aop.Calculator.*(..))")
public Object aroundMethod(ProceedingJoinPoint joinPoint){
Object result = null;
try {
System.out.println("前置通知");
result = joinPoint.proceed(); //调用目标方法
System.out.println("返回通知");
}catch (Throwable e){
System.out.println("异常通知");
e.printStackTrace();
}finally {
System.out.println("后置通知");
}
return result;
}
}
1、aroundMethod 参数里面使用 ProceedingJoinPoint 类型,然后可以通过 .proceed() 调用目标方法。
2、如果目标方法有返回值,那么 aroundMethod 方法也应该有返回值。