一文通透spring的初始化
简述
今天重点分析ApplicationContext初始化时做的事情,我们都只到spring是个IOC和AOP容器,那再我们new一个ApplicationContext,spring内部都做了什么?怎么实现的IOC和AOP?
比如说下面这段代码
@Configuration
@ComponentScan("com.xxx.xxx")
@EnableAspectJAutoProxy
public class MainApplication {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MainApplication.class);
IUser user = context.getBean(IUser.class);
user.sayHi();
}
}
通过new一个AnnotationConfigApplicationContext我们就得到了这个bean容器,还可以添加切面,那再new的时候都做了什么呐?
BeanFactory
这篇文章的基础是懂得BeanFactory,如果不懂可以做做功课或者翻翻之前的文章~Bean的生命周期和BeanPostProcessor再来,简单总结一下BeanFactory。
BeanFactory能干什么,以最主要的DefaultListableBeanFactory
为例
- 注册bean定义
- 通过bean定义生产bean并可以随时获取
- 可以添加bean后置处理器(BeanPostProcessor)来调整bean的创建过程
- 可以一次性创建所有非懒加载单例bean(preInstantiateSingletons)
- 等等
ApplicationContext
有了BeanFactory为啥还要有ApplicationContext呐,其实BeanFactory只是一个给图纸(bean定义)生产产品(bean)的工厂,离我们太遥远了,或者说用起来他麻烦了,甚至依赖注入和AOP都不是BeanFactory实现的
如果单纯使用BeanFactory,需要给他添加依赖注入的后置处理器,需要给他加AOP的后置处理器,才能实现这些功能,而使用ApplicationContext这些活它帮干了,它还可以自动扫描包或者读取配置自动生成bean定义注册到BeanFactory当中,还有一些事件的支持和国际化的支持。
所以为什么有ApplicationContext,ApplicationContext就是把一些我们平时开发用到的功能封装好了,我们开发时直接用就可以实现IOC,AOP,事件等功能
它俩的关系就好比工厂和门店,那有了工厂为啥还有有门店呐?单一职责吗,工厂的技术宅就能看懂图纸,你跟他说中国话他听不懂,所以就有了门店,你简单和门店的人说一下你的需求,门店的人帮你画图纸交给工厂生产,整个过程你不需要和工厂接触
后置处理器
后置处理器分为BeanFactoryPostProcessor和BeanPostProcessor
- BeanPostProcessor
bean后置处理器,beanFactory可以添加BeanPostProcessor,再生成bean的不同时期执行这些后置处理器,简单来说,通过设置后置处理器,可以再bean的创建过程中植入一些自定义逻辑 - BeanFactoryPostProcessor
BeanFactory后置处理器,ApplicationContext可以添加BeanFactoryPostProcessor,再初始化ApplicationContext时会调用这些BeanFactory后置处理器
总结BeanPostProcessor和BeanFactoryPostProcessor都是钩子,前者是存储于beanFactory,再生产bean时候调用,后者存储于ApplicationContext,再初始化ApplicationContext时调用,二者都有很多子类型,以便再不同阶段调用,使代码有很大的扩展性
ApplicationContext
接下来分析ApplicationContext的源码,由于现在都很少用xml这种了,所以我们找了个AnnotationConfigApplicationContext,注解配置的ApplicationContext,也就是现在当然springboot内部用的ApplicationContext,那就开始跟宗AnnotationConfigApplicationContext
的构造方法
public AnnotationConfigApplicationContext(Class>... componentClasses) {
this();
register(componentClasses);
refresh();
}
一共就三局,一个一个跟
this()
调用无参构造方法,首先要调用父类构造方法,父类是GenericApplicationContext
,看看他的构造方法
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
这个简单,内部初始化了一个DefaultListableBeanFactory
,这个好理解,门店的背后肯定是有工厂的,再来看当前类的无参构造方法
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
初始化了一个reader,一个scanner,先看看reader
跟踪reader的构造方法会出现这么一条代码
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
这句话很重要,这里的this.registry就是ApplicationContext,在这里扮演一个bean定义注册器的角色,进入这个方法查看~
具体的代码就不贴了,很长可以自己看看,总结就是像这个bean定义注册器注册了很多个后置处理器类型的bean定义,包括BeanFactoryPostProcessor类型和BeanPostProcessor类型,主要有:
- 配置类解析后置处理器 ConfigurationClassPostProcessor(BeanFactoryPostProcessor)
- @Autowired 注解的处理器 AutowiredAnnotation(BeanPostProcessor)
- @Required属性的注解处理器 RequiredAnnotation(BeanPostProcessor)
- @EventListener解析器 EventListenerMethodProcessor
- 事件监听器工厂 DefaultEventListenerFactory
注意:上面讨论过两种后置处理器存放的位置,而这时添加的后置处理器并没有存放到相应位置,而是以bean的形式存放在bean容器中
至于为什么在这时机添加后置处理器,应该是这些后置处理器都属于读文件、读类的功能,即reader
。
register(componentClasses)
这里的componentClasses就是初始化时传入的唯一参数MainApplication.class
,register都干了什么呐
public void register(Class>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
调用刚才初始化的reader的register方法,这里就要介绍reader的主要作用,就是传入一个类,把类转换为bean定义并注册到初始化时传入的bean定义注册器
所以register方法就是把主配置类(MainApplication)解析为bean定义并完成注册
refresh()
这句就是初始化的核心方法了,内部有很多子方法的调用
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
这么多方法,一个一个来吧
1.prepareRefresh
这个先不管,就是做一些准备工作吗,比如记录一下程序开始的时间什么的
2.beanFactory = obtainFreshBeanFactory()
因为refresh方法是再父类中执行的,而beanFactory是在子类初始化的,所以这句话就是父类管子类要beanFactory,也就是刚才GenericApplicationContext无参构造中初始化的DefaultListableBeanFactory
3.prepareBeanFactory
拿到了beanFactory,再给beanFactory做一次准备工作,比如初始化属性什么的
4.postProcessBeanFactory(beanFactory)
Allows post-processing of the bean factory in context subclasses
这句话相当于给子类一个机会做一些操作,比如添加一些后置处理器进来(因为下一步就要执行后置处理器了,再次之前给一个机会再添加一些后置处理),也是为了代码灵活,查看子类并没有再这一步做什么操作
5.invokeBeanFactoryPostProcessors(beanFactory);
重点来了,字面意思执行BeanFactory后置处理器,看一下代码
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
这里相当于把工作交给一个类PostProcessorRegistrationDelegate
处理,我们先管他叫后置处理委托器,spring使用这种委托模式来让代码规整,也比较符合单一职责
PostProcessorRegistrationDelegate
把后置处理器相关的业务代码从ApplicationContext
中抽离出来
那么继续跟到PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
这个方法,这个比较重要,得贴下代码
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
// 已执行的后置处理器(bean容器中),为防止重复执行
Set processedBeans = new HashSet<>();
// 如果bean工厂是bean定义注册器,比如DefaultListableBeanFactory本身也是可以注册bean定义的注册器
if (beanFactory instanceof BeanDefinitionRegistry) {
// bean定义注册器
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 基础型后置处理器集合
List regularPostProcessors = new ArrayList<>();
// bean定义注册型后置处理器集合
List registryProcessors = new ArrayList<>();
// 循环后置[参数]后置处理器
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 如果是bean定义注册型后置处理器,直接执行postProcessBeanDefinitionRegistry,并存入registryProcessors
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
// 如果是基础型后置处理器,直接执行,并存入regularPostProcessors
else {
regularPostProcessors.add(postProcessor);
}
}
// 开始执行[bean容器中]后置处理器
// 当前bean定义注册型后置处理器集合,为了按循序执行
List currentRegistryProcessors = new ArrayList<>();
// 首先,从bean容器中获取带@PriorityOrdered标识的bean定义注册型后置处理器
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 加入当前集合
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 标记已执行
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 加入registryProcessors
registryProcessors.addAll(currentRegistryProcessors);
// 执行当前bean定义注册型后置处理器集合的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 清空当前bean定义注册型后置处理器集合
currentRegistryProcessors.clear();
// 其次, 从bean容器中获取带@Ordered标识的bean定义注册型后置处理器,逻辑和上一步基本一样
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 多了一个!processedBeans.contains判断,避免后置处理器被多次执行
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 最后, 执行其他的bean定义注册型后置处理器,知道容器中的所有都被执行过
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 执行所有基础型后置处理器的postProcessBeanFactory方法,bean定义注册型后置处理器也是基础型后置处理器的一种,所以也要执行
// 这里的regularPostProcessors来源于[参数]后置处理器
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 如果传入的beanFactory不是bean定义注册器,只是简单的执行了[参数]后置处理器的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 开始执行[bean容器中]普通后置处理器,和执行[bean容器中]bean定义注册型后置处理器基本逻辑差不多,都是按循序执行
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 按@PriorityOrdered, @Ordered, 和无注解,区分优先级
List priorityOrderedPostProcessors = new ArrayList<>();
List orderedPostProcessorNames = new ArrayList<>();
List nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 首先,执行带@PriorityOrdered的.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 其次, 执行带@Ordered的.
List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 最终, 执行其他的
List nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 执行了[bean容器中]基础型后置处理器的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
上面的代码还是比较多,但总结起来也不复杂
首先,后置处理器主要有两种:
1).基础型后置处理器(BeanFactoryPostProcessor)
基础型后置处理器,只有一个方法postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
,可以配置bean工厂,比如bean工厂添加一些bean后置处理器
2).bean定义注册型后置处理器(BeanDefinitionRegistryPostProcessor)
bean定义注册型后置处理器,继承BeanFactoryPostProcessor,所以也属于基础型后置处理器的一种,新增一个方法postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
,增加功能:可以注册一些bean定义
其次,执行后置处理器,那么后置处理器在哪里?从代码里就可以看出
1).【参数】后置处理器
之前ApplicationContext存储了一些BeanFactory后置处理器,可以通过public的addBeanFactoryPostProcessor
方法添加,比如springboot启动时就添加了一些后置处理器,这些后置处理器是用第二个参数:getBeanFactoryPostProcessors()
传给后置处理委托器的
/** AbstractApplicationContext中 */
private final List beanFactoryPostProcessors = new ArrayList<>();
2).【bean容器中】的后置处理器
ApplicationContext引用了DefaultListableBeanFactory
,这个BeanFactory中存放了很多的bean,这些bean有些是后置处理器类型的(比如子类初始化reader时通过AnnotationConfigUtils.registerAnnotationConfigProcessors
方法存入的bean),那么只要通过beanFactory调用getBeanNamesForType就可以获取这些后置处理器,比如
// 通过类型获取所有后置处理器的名字
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 获取到后置处理器
beanFactory.getBean(ppName, BeanFactoryPostProcessor.class);
}
}
存在两个地方的后置处理器,分别通过BeanFactory和getBeanFactoryPostProcessors()传给后置处理委托器,那么下一步后置处理委托器就是执行这两种来源的后置处理器
执行过程就是上面代码,比较有意思,考虑到传入的参数DefaultListableBeanFactory本身就是BeanDefinitionRegistry所以执行逻辑如下
- 执行[参数]后置处理器中的
bean定义注册型
后置处理器postProcessBeanDefinitionRegistry
方法 - 查找bean容器,执行[bean容器中]后置处理器中的
bean定义注册型
后置处理器postProcessBeanDefinitionRegistry
方法,这个过程会按@PriorityOrdered>@Ordered>Other 顺序依次分批执行,执行完一批会重新去bean容器获取一次,直到获取不到为止,这样非常巧妙,如果某个bean定义注册型
后置处理器有注册了一个该类型后置处理器,该后置处理器就会在后续的查找中被找出并执行,即可以用后置处理器添加后置处理器,有点传销的意思 - 执行上两步
bean定义注册型
后置处理器的postProcessBeanFactory
方法 - 执行[参数]后置处理器中
基础型
后置处理器的postProcessBeanFactory
方法 - 查找bean容器,执行执行[bean容器中]后置处理器中的
基础型
后置处理器的postProcessBeanFactory
方法,依然是按@PriorityOrdered>@Ordered>Other批次进行执行,但不会在这期间再次重新查找bean容器
总结:这一步完成了对两种来源的两种类型的beanFactory后置处理器的调用,期间注册型后置处理器注册的新后置处理器也会被执行
6.registerBeanPostProcessors(beanFactory);
beanFactory后置处理器的添加和调用都结束了,下一步就要开始弄bean后置处理了,前面讲过bean后置处理器是存在beanFactory中的,所以参数还是传了个beanFactory
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
同样还是交给了后置处理委托器去处理,上面reader初始化的时候往bean容器里加了一些beanFactory后置处理同时也有bean后置处理器,以bean的形式存储,那总得有人把这些后置处理器给摘出来放到beanFactory的bean后置处理列表里才能再创建时被调用,因为beanFactory的后置处理器存储地点如下
private final List beanPostProcessors = new CopyOnWriteArrayList<>();
但是上面reader却把后置处理器放到了bean容器中,那肯定执行不了啊,所以这一步就是把beanFactory中的bean后置处理器类型的bean定义生产出来放入beanPostProcessors
中,这些bean定义除了reader添加的几个还有大部分是上一步beanFactory后置处理器执行时加入到bean容器的
总结:这一步完成把以bean形式存储在beanFactory中的后置处理器摘出来放到beanFactory中专门存放后置处理器的地方,以便后续创建bean时使用
7.initMessageSource
国际化的一些处理,以后研究
8.initApplicationEventMulticaster
事件处理,以后研究
9.onRefresh
也是一个钩子,默认什么都不做,子类可以覆盖去做点事
10.registerListeners
事件的处理,以后研究
11.finishBeanFactoryInitialization(beanFactory)
这一步就很重要了,看注释Instantiate all remaining (non-lazy-init) singletons
,实例化所有非懒加载的bean,也就是调用beanFactory的preInstantiateSingletons
方法,创建所有单例bean(非懒加载的bean)
12.finishRefresh
结束后的一些操作,比如发布初始化结束事件等
总结
到此,refresh方法分析完了,抛去一些事件国际化相关的辅助代码,主要结合之前的流程总结如下
- 配置主方法注入到bean容器
- 添加一些beanFactory后置处理器和bean后置处理器,还有一些其它的bean至bean定义注册器
- 执行beanFactory后置处理器,分BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor两种,通过BeanFactoryPostProcessor可以配置bean工厂,通过BeanDefinitionRegistryPostProcessor可以注册一些bean定义也配置bean工厂,其间BeanDefinitionRegistryPostProcessor可以注册新的后置处理器,也会再后续执行
- 提取bean容器中bean后置处理器类型的bean,添加到bean工厂的bean后置处理器列表中
- 初始化所有单例非懒加载bean
到此spring启动时所执行重点方法就分析完了,其实按总结来看,就那么几个重点步骤,但是所谓的IOC和AOP到底如何实现的呐,并没有相关代码啊?
其实,这些功能都是通过后置处理器来实现的,也就是spring定义了一套后置处理器执行的规则,并把重点的工作都交给了内置的后置处理器来实现
IOC
spring是一个IOC容器,能把我们写的@Service,@Controller,@Component的类的bean定义注册,并生成bean加入容器,但刚刚我们看了new ApplicationContext
的流程代码,发现用户写的类唯一被注册成bean定义就只有MainApplication.class
那么其他的bean(@Service,@Controller,@Component修饰的)是合适注册为bean定义的?
其实这部分工作就是后置处理器ConfigurationClassPostProcessor
完成的,就是上文read构造时registerAnnotationConfigProcessors
方法注册的后置处理器
ConfigurationClassPostProcessor
翻译过来就是配置类后置处理器,就是专门处理配置类的,它继承了BeanDefinitionRegistryPostProcessor,因此拥有注册bean定义的能力
那么重点看一下它的postProcessBeanDefinitionRegistry
方法
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 省略
processConfigBeanDefinitions(registry);
}
进入processConfigBeanDefinitions,只捡主要代码贴,可自行对照
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// 创建一个解析器,解析@Configuration注解的类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
// 开始解析,这个candidates就是我们传入的MainApplication
parser.parse(candidates);
// 获取解析到的类
Set configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
// 初始化一个reader
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
// 把上面解析到的类转化为bean定义并注册到bean定义注册器(registry)
this.reader.loadBeanDefinitions(configClasses);
}
使用ConfigurationClassParser.parse
进行配置类解析,而这个方法就包含了解析@ComponentScan
,@Import
等注解
@ComponentScan
就是我们制定的扫描包路径,会扫描路径下@Component
注解的类(包括子注解@Configuration
,@Service
等),注册成bean定义,同时会继续递归parse解析扫描到的ConfigurationClass(一般只带有@Configuration
注解),直到把我们指定的所有bean加入bean容器
这里的源码分析可查看文章:spring如何扫描解析bean(注册bean的多种方式)
依赖注入
依赖注入是通过BeanPostProcessor实现的,即AutowiredAnnotationBeanPostProcessor,依然是上文read构造时registerAnnotationConfigProcessors
方法注册的后置处理器,它修改了bean生命周期中填充属性的过程:
- 查询带有
@Autowired
属性 - 通过属性的type在bean容器中使用getBeanByType方式查找要注入的bean
- 反射给属性赋值
细节可以参照文章Spring之@Autowired依赖注入探究
AOP
ConfigurationClassParser.parse
的时候还会扫描@Import注解,如果@Import的类继承了ImportBeanDefinitionRegistrar
就可以自定义注册一些bean(参照:spring如何扫描解析bean(注册bean的多种方式))。
AOP就是使用这种@Import
+ImportBeanDefinitionRegistrar
的方式完成AOP功能可配置的---注解@EnableAspectJAutoProxy
,有则可以AOP,没有则不能AOP
@EnableAspectJAutoProxy
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
// 省略
}
其中引入了AspectJAutoProxyRegistrar
,而AspectJAutoProxyRegistrar
实现了ImportBeanDefinitionRegistrar
,那么这个注解通过这种方式注册了什么bean呐?
答案就是bean后置处理器AnnotationAwareAspectJAutoProxyCreator
,用来再bean创建过程中实现动态代理。
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 注册AnnotationAwareAspectJAutoProxyCreator
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
而AnnotationAwareAspectJAutoProxyCreator
继承了AbstractAutoProxyCreator
继而继承BeanPostProcessor
,创建代理的代码就写在AbstractAutoProxyCreator.wrapIfNecessary
方法里,对其刚兴趣可以参考我之前的AOP系列文章
最后
这篇文章是根据之前的一篇文章改的,主要是因为之前写的有些不对,而且需要这里的知识时又发现很多地方已经忘了,所以这次要画一张大图,把今天总结的逻辑都包含在图中,下次再看,一目了然~
共有 0 条评论