本文已参与「新人创作礼」活动,一起开启掘金创作之路。
Spring AOP可以帮助我们java在不修改源代码的前提下实现功能增强,其底层实现基于java动态代理或者CGLIB。
以往我使用execution选定具体利用AOP扩展哪些类,以及可以模糊匹配......
execution(* com.example.xuexitong.controller..*.*(..))
这样使用很不灵活,因为并不是Service中所有的方法都需要被增强
应用场景
需要灵活用共性需求的地方都可以使用该方案
1、收集上报指定关键方法的入参、执行时间、返回结果等关键信息,用作后期调优
2、关键方法在幂等性前置校验(基于本地消息表)
3、类似于Spring-Retry模块,提供关键方法多次调用重试机制。
4、提供关键方法自定义的快速熔断、服务降级等职责。
5、关键方法的共性入参校验。
6、关键方法在执行后的扩展行为、例如记录日志、启动其他任务等。
首先引入aspectjweaver依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
新建自定义注解,利用@interface关键字定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodExporter {
}
定义切面
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class TestAop {
@Around("@annotation(com.example.xuexitongtwo.aopzhujie.MethodExporter)")
public Object methodExporter(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("方法执行前动作");
// 执行目标方法,获取方法返回值
Object preceed = joinPoint.proceed();
System.out.println("方法执行后动作");
return preceed;
}
}
控制层
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.xuexitongtwo.aopzhujie.MethodExporter;
@RestController
public class TestConTroller {
@MethodExporter
@GetMapping("/test2")
public Integer test2() {
System.out.println("方法执行");
return 1;
}
}
启动项目
写http文件
运行结果
方法执行前动作
方法执行
方法执行后动作