1、快速入门
对于很多java EE开发者而言IOC和AOP这2个词汇应该都比较熟悉了,咱们再复习一下概念:
IOC:控制反转,原来我们需要自己new对象,用了spring后用注解如@Bean、@Component可以让对象由Spring容器统一管理。
AOP: 面向切面编程,它是一种思想,它是对某一类事情的集中处理。比如我们想在很多方法前面都添加日志、数据脱敏等就可以用AOP实现。
2、实战
需求描述:
在springboot项目用aop在所有controller方法执行前实现日志打印的功能。
代码:
1、增加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.7.0</version>
</dependency>
2、需要被打印日志的方法
@RequestMapping("/aop")
@RestController
public class HelloSpringBoot {
@GetMapping("/add")
@LogAnnotation("加法")
public Integer add(@RequestParam("a") Integer a, Integer b){
return a+b;
}
@GetMapping("/sub")
@LogAnnotation("减法")
public Integer sub(){
return 2;
}
@GetMapping("/mul")
@LogAnnotation("乘法")
public Integer mul(Integer a,Integer b){
return a*b;
}
@GetMapping("/div")
@LogAnnotation("除法")
public Integer div(Integer a,Integer b){
return a/b;
}
}
3、添加日志类注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
String value() default "";
}
4、增加切面类
@Component
@Aspect
public class LogAspect {
@Pointcut("@annotation(org.example.annotation.LogAnnotation)")
public void logPointCut(){
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
Signature signature = point.getSignature();
String name = signature.getName();
//获取注解
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
if (annotation!=null){
String value = annotation.value();
System.out.println("annotation:"+value);
}
System.out.println("调用了"+name+"方法,返回值是"+point.proceed());
return point.proceed();
}
}
5、实现效果
3、原理
Spring AOP 的实现原理主要依赖于动态代理和反射技术。当 Spring 容器启动时,它会根据配置文件或注解等元数据信息,来创建代理对象并将其注册到应用程序中。Spring AOP 实现的核心就是利用这些代理对象来实现对目标对象的增强,具体如下:
1、代理对象的创建:Spring AOP 通过动态代理来创建代理对象。对于基于接口的代理,Spring 使用 JDK 动态代理;对于基于类的代理,Spring 使用 CGLIB(Code Generation Library)动态代理。在代理对象的创建过程中,Spring 会根据切面配置信息来决定是否对目标对象进行增强,并生成相应的代理对象。
2、连接点的确定:连接点是在程序执行过程中可以插入切面的点,如方法调用、方法执行、异常抛出等。Spring AOP 通过切点表达式(Pointcut Expression)来确定连接点。切点表达式定义了切面在哪些连接点上执行通知。
3、通知的执行:通知是切面在连接点上执行的动作。在 Spring AOP 中,通知包括了 Before、After、Around、AfterReturning 和 AfterThrowing 等类型的通知。当目标对象的连接点与切点匹配时,相应类型的通知会被执行。
4、增强的应用:通知执行时,会将增强逻辑(Advice)应用于目标对象上,从而实现对目标对象的增强。增强逻辑可以包括日志记录、性能监控、事务管理等。
5、目标对象的调用:最终,代理对象会调用目标对象的方法。如果存在 Around 类型的通知,它会在目标方法执行前后进行拦截,从而允许切面在目标方法执行前后添加额外的逻辑。