AnnotationAwareAspectJAutoProxyCreator后置处理器的BeanDefinition定义信息导入和其对象实例创建过程
步骤1
我们从配置类上的@EnableAspectJAutoProxy 注解入手,进入发现这个注解上又有一个@Import(AspectJAutoProxyRegistrar.class)注解,
了解Spring注解式开发的都知道,@Import是可以导入组件到IOC容器中的,而其中的AspectJAutoProxyRegistrar是实现了ImportBeanDefinitionRegistrar接口,可以实现批量导入组件的自定义信息BeanDefinition到IOC容器中,那么我们就研究一下这个类。
步骤2
进入AspectJAutoProxyRegistrar类中,发现其中重写了registerBeanDefinitions()方法,在这个方法上打一个断点,以debug启动测试方法

步骤3
debug跟进,来到AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
F5一直跟进,来到AopConfigUtil.registerOrEscalateApcAsRequired()方法

会发现,首先判断当前容器中是否包含org.springframework.aop.config.internalAutoProxyCreator组件的定义,
debug发现当前容器中没有,if 没有进去,接着往下走。
cls为org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator类型,通过RootBeanDefinition对其进行包装,
通过registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);将其加入到IOC容器中,并命名为org.springframework.aop.config.internalAutoProxyCreator,
到这里容器中就有internalAutoProxyCreator类型的组件了,其实这个组件实际类型为AnnotationAwareAspectJAutoProxyCreator。
那么向容器中加入AnnotationAwareAspectJAutoProxyCreator有啥用呢?我们就来研究一下AnnotationAwareAspectJAutoProxyCreator
步骤4
AnnotationAwareAspectJAutoProxyCreator的类结构:

进入AnnotationAwareAspectJAutoProxyCreator,通过查看其父类AbstractAutoProxyCreator发现AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor及BeanFactoryAware

查看SmartInstantiationAwareBeanPostProcessor发现他是BeanPostProcessor的子接口,
BeanPostProcessor是后置处理器的总接口,那么也就说明AbstractAutoProxyCreator是后置处理器,而它又实现BeanFactoryAware
所以在初始化AbstractAutoProxyCreator的时候,会通过setBeanFactory()向其注入BeanFactory,
接下来就看看AbstractAutoProxyCreator作为后置处理器和BeanFactory都干了些啥
步骤5
首先我们需要加一些断点,辅助我们调试,我们需要在org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.setBeanFactory(BeanFactory)上打一个断点
查看作为BeanFactoryAware啥时候调用了setBeanFactory()方法。然后在org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(Class<?>, String)
及org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(Object, String)上个加一个断点,查看作为后置处理器啥时候调用了这两个方法
之后在org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.setBeanFactory(BeanFactory)上加一个断点,因为他重写了父类的setBeanFactory()方法。最后在
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.initBeanFactory(ConfigurableListableBeanFactory)上加一个断点,因为他重写了父类的initBeanFactory()方法
步骤6
从头看起,测试方法中,开始先new了一个AnnotationConfigApplicationContext传入一个配置类,在其构造方法上加一个断点,跟进查看

看到先注册配置类然后调用了refresh()方法,F5进入refresh()方法,看到调用了registerBeanPostProcessors(beanFactory)方法

进入registerBeanPostProcessors(beanFactory)方法,一直来到PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this) 中,
看到先通过beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);获得容器中已经定义了的所有BeanPostProcessor类型的组件名,
并向容器中加了一下额外的后置处理器。

步骤7
接着跟进,后面通过循环将后置处理器进行分组,因为后置处理器可以通过实现PriorityOrdered接口,定制优先级。
接着下来看到,优先注册实现PriorityOrdered接口的后置处理器,
在来注册实现Ordered接口的后置处理器,
最后注册没有实现优先级接口的后置处理器

走到实现Ordered接口的后置处理器的循环中,发现org.springframework.aop.config.internalAutoProxyCreator组件也在其中

上面我们已经提到过,其实internalAutoProxyCreator就是AnnotationAwareAspectJAutoProxyCreator,
而AnnotationAwareAspectJAutoProxyCreator也是一个后置处理器,那么AnnotationAwareAspectJAutoProxyCreator实现了Ordered接口吗 ?
通过查看源码发现,他的父类AbstractAutoProxyCreator继承了ProxyProcessorSupport,而ProxyProcessorSupport实现了Ordered接口,
那么就看看AnnotationAwareAspectJAutoProxyCreator是如何被创建出来的。
步骤8
在for循环中调用了 beanFactory.getBean(ppName, BeanPostProcessor.class)方法,F5跟进
来到AbstractBeanFactory.doGetBean(String, Class, Object[], boolean)方法,
一路来到getSingleton()缓存方法,获得bean,但由于容器第一次创建,根本就获取不到,
就来到DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory<?>)方法,就通过singletonFactory.getObject();
创建bean,实际就是创建后置处理器然后保存到容器中

那么容器是如何创建internalAutoProxyCreator【AnnotationAwareAspectJAutoProxyCreator】的呢 ?
跟进singletonFactory.getObject();
一直来到AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[])方法

进入doCreateBean()方法中,对internalAutoProxyCreator进行创建

之后就是对后置处理器对象进行属性赋值

后有一个initializeBean(beanName, exposedObject, mbd)就是初始化处理器对象,进入初始化方法

有一个invokeAwareMethods(beanName, bean)方法,进到其中发现,在判断bean是否是XXXAware接口的实现,
而通过前面分析,我们的internalAutoProxyCreator【AnnotationAwareAspectJAutoProxyCreator】实现了BeanFactoryAware接口,
所以这里就是在为其赋值,先调用其父类的方法AbstractAdvisorAutoProxyCreator.setBeanFactory(BeanFactory)

调用父类的setBeanFactory()后,又调用了initBeanFactory((ConfigurableListableBeanFactory) beanFactory)方法,初始化beanFactory,
最终调到AnnotationAwareAspectJAutoProxyCreator.initBeanFactory(ConfigurableListableBeanFactory)中的initBeanFactory()方法,
在其中创建了反射的通知工厂和构建通知适配器。

invokeAwareMethods(beanName, bean)方法执行完毕
后会调用applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)方法,这是在调用所有后置处理器的postProcessBeforeInitialization()方法
之后又调用invokeInitMethods(beanName, wrappedBean, mbd)方法,这是在调用所有的bean的初始化方法,
之后有调用applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)方法,这是在调用所有后置处理器的postProcessAfterInitialization()方法。
至此,后处理器就创建完成了,PostProcessorRegistrationDelegate#registerBeanPostProcessors()方法内,
调用beanFactory.addBeanPostProcessor(postProcessor),将BeanPostProcessor添加到beanFactory当中

步骤9
以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程,当AnnotationAwareAspectJAutoProxyCreator被创建出来,
后来的bean的创建都需要通过这个后置处理器,下面我们就看一下,AnnotationAwareAspectJAutoProxyCreator作为后置处理器都做了些啥
AnnotationAwareAspectJAutoProxyCreator后置处理器的BeanDefinition定义信息导入和其对象实例创建过程的更多相关文章
- 2.3 spring5源码系列---内置的后置处理器PostProcess加载源码
本文涉及主题 1. BeanFactoryPostProcessor调用过程源码剖析 2. 配置类的解析过程源码 3. 配置类@Configuration加与不加的区别 4. 重复beanName的覆 ...
- Spring-Spring Bean后置处理器
Spring Bean后置处理器 BeanPostProcessor接口定义回调方法,你可以实现该方法来提供自己的实例化逻辑,依赖解析逻辑等.你也可以在Spring容器通过插入一个或多个BeanPos ...
- spring的后置处理器——BeanPostProcessor以及spring的生命周期
后置处理器的调用时机 BeanPostProcessor是spring提供的接口,它有两个方法——postProcessBeforeInitialization.postProcessAfterIni ...
- 【Spring注解驱动开发】关于BeanPostProcessor后置处理器,你了解多少?
写在前面 有些小伙伴问我,学习Spring是不是不用学习到这么细节的程度啊?感觉这些细节的部分在实际工作中使用不到啊,我到底需不需要学习到这么细节的程度呢?我的答案是:有必要学习到这么细节的程度,而且 ...
- Spring中Bean的后置处理器
以下内容引用自http://wiki.jikexueyuan.com/project/spring/bean-post-processors.html: Bean后置处理器 BeanPostProce ...
- spring源码学习(四)-spring生命周期用到的后置处理器
生命周期的九大后置处理器 第一次调用后置处理器org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory# ...
- Spring Bean的生命周期、后置处理器、定义继承
目录: 了解Spring的基本概念 Spring简单的示例 Spring Bean的定义及作用域 1.Bean的生命周期 Bean的生命周期可以简单的理解为:Bean的定义——Bean的初始化——Be ...
- BeanPostProcessor后置处理器原理以及ApplicationListener原理
BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的 1.BeanFactoryPostProcessor:BeanFactory的后置处理器; 在Bean ...
- Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理
Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理 前言 上一篇分析了BeanFactoryPostProcessor的作用,那么这一篇继续 ...
- spring 后置处理器BeanFactoryPostProcessor和BeanPostProcessor的用法和区别
主要区别就是: BeanFactoryPostProcessor可以修改BEAN的配置信息而BeanPostProcessor不能,下面举个例子说明 BEAN类: package com.spring ...
随机推荐
- OV7670寄存器说明
I2C读出来的内容的地址,比datasheet给出的小9? add- 0x0 = 0x0add- 0x1 = 0x76add- 0x2 = 0x73add- 0x3 = 0x4add- 0x4 = 0 ...
- 手撸原生js放大镜效果
普及知识:放大镜特效涉及到的几个值 offsetWidth 获取元素的宽度offsetHeight 获取元素的高度offsetLeft父元素没有定位时,获取元素距离页面的左边距,父元素有定位时 ...
- Superset 用户集成方案
注意,一下内容来自外网浏览器翻译,本人使用了将superset集成进入第三方系统,superset采用自定义身份验证+第三系统iframe嵌入方式,但是这个方式存在一个问题,iframe与redire ...
- react报错Can't resolve 'react' in 'E:\reactweb\preact\my-app\node_modules\react-dom\cjs'
执行如下: npm install -g react npm install react --save 类似这种依赖项(react,react-dom 等)报错,哪个报错执行哪个即可 执行上述两句就 ...
- Maven配置代理
Maven配置代理 找到settings.xml文件: 通常位于Maven安装目录下的conf文件夹中.或者位于用户目录下的.m2文件夹中(例如:$HOME/.m2/settings.xml). 编辑 ...
- useradd usermod userdel passwd groupadd groupmod groupdel等命令详解
linux命令参数记忆有些模糊了,记录下.学而时习之,不亦说乎? 1.useradd命令用来建立用户帐号和创建用户的起始目录,使用权限是终极用户.创建新用户useradd,默认的用户家目录会被存放在/ ...
- FreeSql学习笔记——2.插入
前言 由于还没有表结构,就先从新增开始,插入一些数据后才好做查询.修改.删除操作. 初始化 前面注入FreeSql时设置过自动同步表结构,那么就不用管数据库了,只需要在项目中定义实体,就会自动生成表结 ...
- [ABC213G] Connectivity 2 题解
好好好. 我们设当前处理 \(i\) 的答案,那么最后的图就可以分成两个部分:\(1\) 所在的联通块和其他,根据乘法原理,答案就是它们二者方案的乘积. 设 \(f_s\) 表示集合 \(s\) 中所 ...
- Docker 镜像存储目录的位置修改教程
以下是在 Linux 系统中修改 Docker 镜像存储目录位置的一般步骤: 查看当前 Docker 的默认存储目录:使用docker info命令可以查看 Docker 存储驱动程序和默认存储位置, ...
- 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
引子:那个让运维集体加班的夜晚 "凡哥!线上服务响应时间飙到10秒了!"凌晨1点,实习生小李的语音带着哭腔. 监控大屏上,JVM堆内存曲线像坐了火箭--刚扩容的16G内存,30分钟 ...