SpringBoot源码解析自动装配

自动加载BeanFactoryPostProcessor


在SpringBoot下,我们并没有告诉Spring应该扫描那个xml配置,也没有告诉Spring是否需要开启自动注入。在SpringBoot下,我们只要使用了@Component ,@Bean和@Autowired的组合标签即可实现Bean的自动注入。那Spring又是如何帮我们关联上Bean的呢?

生成context

要了解这个问题,我们还是需要从SpringBoot的启动过程说起。
在这里插入图片描述
在Boot的run方法中,对帮我们创建出一个上下文context对象,来看下这个createApplicationContext方法:

在这里插入图片描述
而applicationContextFactory又是这样定义的:
在这里插入图片描述
根据DEFAULT的定义,最终帮我们生成的context是AnnotationConfigServletWebServerApplicationContext:
在这里插入图片描述
其构造方法如下:
在这里插入图片描述
在SpringBoot帮我们创建AnnotationConfigServletWebServerApplicationContext时,会去构建AnnotatedBeanDefinitionReader对象,在其构造方法内会去调用registerAnnotationConfigProcessors方法:
在这里插入图片描述
而在registerAnnotationConfigProcessors方法内
在这里插入图片描述
在这里插入图片描述
在这边会完成BeanName=“org.springframework.context.annotation.internalConfigurationAnnotationProcessor” 和ConfigurationClassPostProcessor的绑定。

下面我们再来看下AnnotationConfigServletWebServerApplicationContext构造器里的scanner属性的赋值逻辑:
在这里插入图片描述
我们可以看到,这边会调用ClassPathBeanDefinitionScanner的构造方法:
在这里插入图片描述
在构造器内部又调用了registerDefaultFilters方法,一起来看下:
在这里插入图片描述
可以看到,将Component 这个注解加入到了includeFilters里面。看includeFilters的取名,应该是需要包含Component这个注解的意思。ok,到这边我们已经将Boot帮我们创建的BeanFactory看完了。

Spring刷新

现在我们需要将目光放回Spring启动的流程了,Spring的大体启动流程,详情请见上一篇。
在这里插入图片描述
在上一章节中我们有讲到,invokeBeanFactoryPostProcessors会执行BeanFactoryProcesser,对BeanDefinition进行增强,现在我们简单的看会下这个方法:
在这里插入图片描述
可以看到,首先会调用invokeBeanFactoryPostProcessors方法,一起来看下:
在这里插入图片描述
在这个方法中,会调用getBeanNamesForType获取当前BeanFactory中实现了BeanDefinitionRegistryPostProcessor接口的BeanFactoryPostProcesser。还记得在SpringBoot帮我们创建context中会将BeanName=“org.springframework.context.annotation.internalConfigurationAnnotationProcessor” 和ConfigurationClassPostProcessor进行绑定吗?我们来看下ConfigurationClassPostProcessor的类层次结构图:
在这里插入图片描述
所以此时postProcessorNames中只会有一个变量:org.springframework.context.annotation.internalConfigurationAnnotationProcessor。
下面就是执行invokeBeanDefinitionRegistryPostProcessors方法了:在这里插入图片描述
这里面的postProcessor,实际就是ConfigurationClassPostProcessor,所以这边调用的也就是ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法:
在这里插入图片描述
在方法内部,又会去调用processConfigBeanDefinitions方法,看名次,处理配置了的BeanDefinition,看下processConfigBeanDefinitions方法:
在这里插入图片描述
方法内部开始的for循环,第一次进入时会选出我们main方法所在的class对的BeanDefinition,放入candidates的set中。再后面会执行parse方法。

先简单看下checkConfigurationClassCandidate是如何判断注解是否可用的:
在这里插入图片描述
在这里插入图片描述
会依据这个顺序判断当前BeanDefinition的注解是否是可识别的注解。

现在我来看下parse方法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这边我们可以看到一堆对SpringBoot中注解的处理。我们以ComponentScan注解处理为例:会调取到ClassPathScanningCandidateComponentProvider的 scanCandidateComponents方法:
在这里插入图片描述
在这个方法中,会加载我们在Spring boot上配置的@ComponentScan下的路径,默认是以main方法所在路径。
获取到扫描路径之后,会加载该路径下的所有文件,然后一个一个文件去遍历,如果通过了isCandidateComponent方法的检测,才会保留下来。我们来看下这个方法:
在这里插入图片描述
还记得SpringBoot在帮我们创建context时,在设置scanner属性的时候,会将Component注解放入includeFilters吗?现在,在isCandidateComponent方法中,就会检测当前扫描出来的class是否有注解,且其注解是否存在于includeFilters中。这样就可以将当前路径下有Component注解的class找出来了。

SpringBoot注解

通过上面的介绍,我们可以得知,SpringBoot在启动时,会出发Spring的BeanFactoryPostProcessor,然后会根据当前路径找到有相应注解的Class。

下面我们再来看下Boot的@SpringBootApplication注解:
在这里插入图片描述
再来看看@EnableAutoConfiguration注解“
在这里插入图片描述
所以当出发Spring的注解解析之后,一定会加载AutoConfigurationImportSelector这个Class,在这个类内部有方法:
在这里插入图片描述
后面会根据EnableAutoConfiguration这个Bean去spring.factory中加载一大堆的Class:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值