实现AOP需要用到aspectj的注解,这里我们先要在IOC的基础上引入依赖:
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
<version>5.3.1version>
dependency>
然后需要在Spring配置文件中打开自动代理:
<aop:aspectj-autoproxy/>
1、前置通知
@Before("execution(public int com.lu.Spring.aop.CaculatorImpl.add(int , int ))")
public void beforeMethod(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
String s = Arrays.toString(joinPoint.getArgs());
System.out.println("[日志信息]:前置方法-----> 方法:"+signature.getName()+", 参数:"+s);
}
利用@Before(“execution(public int com.lu.Spring.aop.CaculatorImpl.add(int , int ))”)标识的方法为前置通知。
execution(public int com.lu.Spring.aop.CaculatorImpl.add(int , int ))表示切入点。
通知所在的对应类要用@Aspect标识。
2、返回通知
@AfterReturning(value = "execution(* com.lu.Spring.aop.*.*(..))",returning = "result")
public void Returning(JoinPoint joinPoint,Object result){
Signature signature = joinPoint.getSignature();
System.out.println("[日志信息]:返回方法-----> 方法:"+signature.getName()+", 结果:"+result);
}
返回通知注意要在@AfterReturning中设置returning = "result"属性,对应的方法参数要含有Object result接受返回结果。
由于每个通知都需要切入点,过多的书写较为麻烦这里直接设置一个公用的切入点:

3、异常通知
//异常通知
@AfterThrowing(value = "pointcut()",throwing = "e")
public void AfterThrowing(JoinPoint joinPoint, Throwable e){
Signature signature = joinPoint.getSignature();
System.out.println("[日志信息]:异常方法-----> 方法:" + signature.getName() + ", 结果:" + e);
}
只有核心方法出现异常时才会执行异常通知。
4、后置通知
//后置通知
@After("pointcut()")
public void After(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
System.out.println("[日志信息]:后置方法-----> 方法:" + signature.getName() + ", 执行结束");
}
只有核心方法执行成功最后执行的代码(finally)。
5、环绕通知
环绕通知包含上面四种通知,可以实现他们四种通知组合使用的效果。
@Around("pointcut()")
public Object Surround(ProceedingJoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
String s = Arrays.toString(joinPoint.getArgs());
Object result = null;
try {
System.out.println("[日志信息]:环绕通知-----> 方法:" + signature.getName() + "执行前, 参数:" + s);
result = joinPoint.proceed();
System.out.println("[日志信息]:环绕通知-----> 方法:" + signature.getName() + "执行后返回, 结果:" + result);
} catch (Throwable e) {
System.out.println("[日志信息]:异常方法-----> 方法:" + signature.getName() + ", 结果:" + e);
} finally {
System.out.println("[日志信息]:后置方法-----> 方法:" + signature.getName() + ", 执行结束");
}
return result;
}
注意环绕通知的参数是ProceedingJoinPoint joinPoint。
相同方法的切面进行嵌套时,外面的优先级更高。
也可以在切面类利用@Order()注解设置优先级,value值越小优先级越高。
基于xml和基于注解的AOP实现的效果都是一样的,只是实现的语法不同。这里我们利用注解方法来实现上面所述的几个通知。
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.lu.Spring.aop.*.*(..))"/>
<aop:aspect id="LogerAspect" ref="logerAspect">
<aop:before method="beforeMethod" pointcut-ref="pointcut">aop:before>
<aop:after-returning method="Returning" pointcut-ref="pointcut" returning="result" >aop:after-returning>
<aop:after-throwing method="AfterThrowing" pointcut-ref="pointcut" throwing="e">aop:after-throwing>
<aop:after method="After" pointcut-ref="pointcut">aop:after>
<aop:around method="Surround" pointcut-ref="pointcut">aop:around>
aop:aspect>
aop:config>