SpringBoot启动流程分析(五):SpringBoot自动装配原理实现
2020-12-13 03:36
标签:综合 回顾 原理 ISE ssl 梳理 imp 删除 hello SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: 笔者注释版Spring Framework与SpringBoot源码git传送门:请不要吝啬小星星 自定义Starter: SpringBoot应用篇(一):自定义starter 上一篇文章,通过分析refresh()方法中的invokeBeanFactoryPostProcessors()方法,分析了IoC容器的初始化过程,这一节从代码上如下所示,接上一节ConfigurationClassParser类中的parse()方法,接着分析SpringBoot的自动装配原理。 对这个注解详细大家一定非常熟悉了。再来好好看看这个注解。 接着看@EnableAutoConfiguration OK,看到@Import(AutoConfigurationImportSelector.class)导入了一个重要的类AutoConfigurationImportSelector。 至于怎么从章节一中提到的ConfigurationClassParser类中的parse()===>processDeferredImportSelectors()==>AutoConfigurationImportSelector#selectImports(),篇幅有限不做过多介绍。 List 我们来看一下getCandidateConfigurations()方法是怎么拿到这些自动配置类的。 是不是又看到一个十分熟悉的方法loadFactoryNames(),没错,其实我们在分析SpringBoot启动流程的第一篇文章的时候,就已经分析了,SpringBoot是如何从META-INF/spring.factories中加载指定key的value的。ok,我们在这里再次回顾一遍。 看看loadFactoryNames()方法 debug,看看要从META-INF/spring.factories中加载的类的key,如下图所示:org.springframework.boot.autoconfigure.EnableAutoConfiguration 回到selectImports()方法,debug,跳过List 竟然有110个,那这些类都在哪里呢?看spring-boot-autoconfigure(当然在SpringBoot的工程中,也不止这一个依赖包中存在该配置文件)工程下的META-INF/spring.factories,我们能看到org.springframework.boot.autoconfigure.EnableAutoConfiguration定义了一大堆。 其中还有一个com.demo.starter.config.DemoConfig是我自定义的starter。如下所示,我在测试工程中添加了自定义starter的依赖,所以SpringBoot就能扫描到。 继续看Set configurations = filter(configurations, autoConfigurationMetadata);该行代码将会过滤掉不需要装配的类。过滤的逻辑有很多,比如我们常用的@ConditionXXX注解。如下所示: 至于如何将这些类解析成BeanDefinition并注册进beanDefinition中的,和上一节讲的过程是一样的,不再赘述了。 debug,跳过refresh()方法中的invokeBeanFactoryPostProcessors(beanFactory);方法。如下图所示,最终在beanFactory的BeanDefinitionMap中找到了自定义starter中的自动装配的类。 综合本文和上一篇博文我们详细的梳理了IoC容器的初始化过程,到此IoC容器的初始化过程就结束了。 原创不易,转载请注明出处。 如有错误的地方还请留言指正。 SpringBoot启动流程分析(五):SpringBoot自动装配原理实现 标签:综合 回顾 原理 ISE ssl 梳理 imp 删除 hello 原文地址:https://www.cnblogs.com/hello-shf/p/11057861.html
一、前言
1 // ConfigurationClassParser类
2 public void parse(Set
二、SpringBoot自动装配原理。
2.1、@SpringBootApplication注解
1 @Target(ElementType.TYPE)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Documented
4 @Inherited
5 @SpringBootConfiguration
6 @EnableAutoConfiguration
7 @ComponentScan(excludeFilters = {
8 @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
9 @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
10 public @interface SpringBootApplication {
11 ...
12 }
1 @Target(ElementType.TYPE)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Documented
4 @Inherited
5 @AutoConfigurationPackage
6 @Import(AutoConfigurationImportSelector.class)
7 public @interface EnableAutoConfiguration {
8 ...
9 }
2.2、AutoConfigurationImportSelector
1 // AutoConfigurationImportSelector类
2 //自动装配
3 @Override
4 public String[] selectImports(AnnotationMetadata annotationMetadata) {
5 if (!isEnabled(annotationMetadata)) {
6 return NO_IMPORTS;
7 }
8 AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
9 .loadMetadata(this.beanClassLoader);
10 AnnotationAttributes attributes = getAttributes(annotationMetadata);
11 //获取所有的自动配置类(META-INF/spring.factories中配置的key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的类)
12 List
// AutoConfigurationImportSelector类
1 protected List// SpringFactoriesLoader类
1 public static List1
1 @ConditionalOnBean:容器中有指定的Bean
2 @ConditionalOnClass:当类路径下有指定的类
3 @ConditionalOnExpression:基于SpEL表达式作为判断条件
4 @ConditionalOnJava:基于JVM版本作为判断条件
5 @ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
6 @ConditionalOnMissingBean:当容器中没有指定Bean的情况下
7 @ConditionalOnMissingClass:当类路径下没有指定的类
8 @ConditionalOnNotWebApplication:当前项目不是Web项目
9 @ConditionalOnProperty:配置文件中指定的属性是否有指定的值
10 @ConditionalOnResource:类路径下是否有指定的资源
11 @ConditionalOnSingleCandidate:当指定Bean在容器中只有一个,或者虽然有多个但是指定首选Bean
12 @ConditionalOnWebApplication:当前项目是Web项目的条件下
文章标题:SpringBoot启动流程分析(五):SpringBoot自动装配原理实现
文章链接:http://soscw.com/essay/27945.html