spring AOP 执行流程

1,007 阅读2分钟

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

使用实例:

术语:

Pointcut(切入点):使用@Pointcut注解以正则表达式的方式来描述切面类的作用范围。例子中定义了作用范围为:execution(* com.vey.springaop.service..(..))即service包下的所有类。

Advice(通知):使用@Before,@After,@Around,@AfterReturn,@AfterThrowing,来描述什么时候执行切面逻辑以及需要执行的切面逻辑是什么,Advice相当于拦截器。例子中使用@Around会在Joinpoint前后分别执行打印入参和输出结果。

Joinpoint(连接点):由@Pointcut定义的作用范围,需要执行具体切面逻辑的方法。例子中定义的@Pointcut为service包下的所有类,该类下所有的接口都可以看做是一个Joinpoint。

Aspect(切面):对应我们定义的切面类LogAspect。他是Pointcut和Advice的合集。

Weaving(织入):把切面应用到目标对象来创建代理对象。也就是把LogAspect应用的UserServiceImpl生成代理对象,使所有接口都会执行打印日志逻辑的过程。

AOP入口:BeanPostProcessor

image.png

AbstractAutowireCapableBeanFactory#initializeBean

   BeanPostProcessor#postProcessAfterInitialization
   
      AbstractAutoProxyCreator#wrapIfNecessary
         
         AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean 获取该对象的所有Advisors
             
         AbstractAutoProxyCreator#createProxy 为该对象创建代理对象。

AOP可以拆分 1,Bean 初始化阶段:

  • Spring 容器启动时,根据配置或注解 (@Aspect 和 @EnableAspectJAutoProxy),检测所有定义的切面(PointCut 和 Advice)。
  • 使用 BeanPostProssor 为目标类创建代理对象
  • 根据目标类是否实现接口 使用jDK 动态代理或者 CGlib代理

2,获取代理对象: 当目标类被注入或者调用时,获取代理对象而非目标对象本身。

3,方法调用 调用目标对象的方法时,先进入代理对象的拦截器链而非目标方法

4,拦截器链执行 spring AOP 为代理方法生成一个拦截器链(MethodInterceptor),按照顺序依次执行拦截器链,调用切面方法和目标方法

5,方法执行完成

image.png