Spring Aop 源码增强获取分享

作者:? 时间:2023-06-22 21:59:22 

1 前言

在前文中,已经讲述了 AOP 的后置处理器使用和方法,在本文中继续分享增强信息相关的源码,这里才是 AOP 的核心代码。

2 spring 增强器

之前已经讲述了 spring AbstractApplicationContext.refresh 方法,在以下方法中都会处理会处理 BeanPostProcessor 接口。

  • invokeBeanFactoryPostProcessors

  • registerBeanPostProcessors

  • finishBeanFactoryInitialization

增强器的获取,就是提取 @Aspect 注解标记的内容,这个操作一般是在后置处理器中进行处理,在 refresh 方法中调用 finishBeanFactoryInitialization 步骤中进行实现,最终可以追溯到 AbstractAutoProxyCreator.postProcessAfterInitialization。Spring 容器中注册的 AnnotationAwareAspectJAutoProxyCreator 父类就是 AbstractAutoProxyCreator ,继而调用 postProcessBeforeInstantiation 方法获取代理对象。

Spring Aop 源码增强获取分享

在实例化之后,初始化之后会调用 postProcessAfterInitialization 方法,

如下图所示:

Spring Aop 源码增强获取分享

如果有 @Aspect 注解的切面,则将通过 AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean 方法进行获取并放入缓存中。

Spring Aop 源码增强获取分享

Spring Aop 源码增强获取分享

这里的 findCandidateAdvisors 方法的解析和追踪,获取增强器需要追踪 AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors() 方法,其又调用了 BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors() 方法,主要的作用就是为了获取切面逻辑,即获取增强器。

Spring Aop 源码增强获取分享在这里 this.advisorFactory.getAdvisors(factory) 是获取增强器的最终实现方法,在 ReflectiveAspectJAdvisorFactory 工程方法中,可以看到以下内容,这里采用的是委托模式:

Spring Aop 源码增强获取分享

以上是获取增强器的核心逻辑,对于如何解析切面逻辑的注解,则还需要从以下方法进行着手分析,主要就是 getPointcut 方法。

Spring Aop 源码增强获取分享

在该方法中,主要实现了以下功能:

  • 1 获取切点的信息,切点信息一般是指获取注解表达式的信息。

  • 2 根据切点信息生成增强实现,所有的实现类都由 InstantiationModelAwarePointcutAdvisorImpl 进行统一的封装。

Spring Aop 源码增强获取分享

这里的 instantiateAdvice 方法即是获取切面逻辑

Spring Aop 源码增强获取分享

invokeAdviceMethod 这个方法就是实际调用的方法。

Spring Aop 源码增强获取分享

findCandidateAdvisors 查找所有的增强器的解析,但是对于所有的增强器,不一定能适用于当前 Bean,还需要挑选适合的增强器,满足配置的通配符的增强器。这就用到了 findAdvisorsThatCanApply

Spring Aop 源码增强获取分享

BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors() 来获取所有的 Advisor。其核心逻辑如下图所示:

  • 1 获取所有的 beanName,这个 Spring 提供了 BeanFactoryUtils.beanNamesForTypeIncludingAncestors 方法来获取容器中所有的 beanName 信息。

  • 2 遍历所有的 beanName , 并找出声明有 AspectJ 注解的类。

  • 3 对标记为 AspectJ 注解的类进行增强器的提取。

  • 4 将提取增强的结果放入 advisorsCache 中。

以上便是获取增强器的全部过程,总结来说 wrapIfNecessary getAdvicesAndAdvisorsForBean buildAspectJAdvisors 都是核心的方法。

3 总结

本文讲了获取增强信息获取的源码,主要核心方法为wrapIfNecessarygetAdvicesAndAdvisorsForBean buildAspectJAdvisors,在后续文中将继续 AOP 代码的分享。

来源:https://juejin.cn/post/7087465088617021448

标签:Spring,Aop,源码,获取
0
投稿

猜你喜欢

  • Android 进程间通信实现原理分析

    2022-01-05 10:27:35
  • C#使用读写锁三行代码简单解决多线程并发的问题

    2023-08-16 12:15:39
  • 基于WPF实现绘制地铁路线图

    2023-09-08 13:23:12
  • Java Swing中JTable渲染器与编辑器用法示例

    2022-11-02 09:23:13
  • AnyChat的视频会议程序实例详解

    2022-05-12 01:03:43
  • 详解Java 自动装箱与拆箱的实现原理

    2022-08-16 11:35:51
  • 使用纯Java实现一个WebSSH项目的示例代码

    2023-03-11 11:32:20
  • JDK1.8中ArrayList是如何扩容的

    2023-01-20 19:04:47
  • 使用PageHelper插件实现Service层分页

    2023-03-06 00:40:39
  • Java动态代理模式的深入揭秘

    2023-07-27 23:41:25
  • Java利用MessageFormat实现短信模板的匹配

    2023-02-19 11:41:54
  • SpringMVC如何获取表单数据(radio和checkbox)

    2022-02-19 05:27:01
  • java多线程编程之join方法的使用示例

    2022-10-06 05:09:38
  • springboot自动配置原理以及spring.factories文件的作用详解

    2021-12-20 20:19:27
  • Spring Boot提高开发效率必备工具lombok使用

    2022-05-21 08:22:38
  • c# 获得当前绝对路径的方法(超简单)

    2021-06-18 05:23:31
  • Java JNDI案例详解

    2022-06-09 07:56:35
  • java8中:: 用法示例(JDK8双冒号用法)

    2023-11-25 06:21:21
  • java实现上传文件类型检测过程解析

    2023-11-09 12:04:21
  • 解决springcloud中Feign导入依赖为unknow的情况

    2022-02-03 14:05:45
  • asp之家 软件编程 m.aspxhome.com