目录
3.2 @Import(AutoConfigurationImportSelector.class)
1.@SpringBootApplication
来看一下自动装配的起点:@SpringBootApplication
点进去看下@SpringBootApplication源码:
三个Java元注解:@Target、@Retention、@Documented。
@Inherited:如果一个类用上了@Inherited修饰的注解,那么其子类也会继承这个注解。具体可以查看这篇博文:https://blog.csdn.net/qq_43390895/article/details/100175330
@SpringBootConfiguration:三个Java元注解:@Target、@Retention、@Documented,加上一个Spring的@Configuration
由此我们可以知道@SpringBootApplication等同于@Configuration、@ComponentScan、@EnableAutoConfiguration
2.@ComponentScan
SpringBoot默认配置了两个自定义的过滤器TypeExcludeFilter和AutoConfigurationExcludeFilter
TypeExcludeFilter作用:提供TypeFilters从中加载BeanFactory并自动应用于SpringBootApplication扫描的排除项。等同于:
@ComponentScan(excludeFilters = @Filter(类型= FilterType.CUSTOM,类= TypeExcludeFilter.class))
AutoConfigurationExcludeFilter:自动配置扫描过滤器。作用:如果扫描到一个类配置了@Configuration并且该类也配置了@EnableAutoConfiguration内自动装配的216个注解其中之一,那么将其过滤掉。(说白了就是如果该类上打了216个自动装项的注解,那么就将该类装配进Spring容器。具体这216个自动装配注解哪里来的,本文下面会解释)
3.@EnableAutoConfiguration
点进源码和上面一样,具体功能由@AutoConfigurationPackage和@Import(AutoConfigurationImportSelector.class)两个注解实现。
3.1 @AutoConfigurationPackage
可以看到@AutoConfigurationPackage具体功能由@Import(AutoConfigurationPackages.Registrar.class)实现。
@Import注解是由 Spring 提供的,作用是将某个类实例化并加入到 Spring IoC 容器中。所以我们要想知道@Import注解究竟实现了什么功能就需要了解Registrar这个类里包含了哪些方法。
determineImportsf方法在项目运行的时候并没有触发断电,查阅官方文档解释如下:
而registerBeanDefinitions方法,触发断点后发现new PackageImport(metadata).getPackageName()方法返回的就是@SpringBootApplication注解所在的类的包名。所以@AutoConfigurationPackage注解的作用是扫描与@SpringBootApplication标注的类同一包下的所有组件。
3.2 @Import(AutoConfigurationImportSelector.class)
这个类着重看selectImports方法,由getAutoConfigurationEntry方法获取自动配置条目。
然后我们再进入到这个叫做getCandidateConfigurations的方法中,这个方法名告诉我们这个方法的作用是获取候选配置。
从断言处我们已经可以发现一些端疑了,发现springboot去"META-INF/spring.factories"路径下寻找自动装配类。继续跟进SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass()方法,再跟进loadSpringFactories(classLoaderToUse)
终于看到了自动装配路径:"FACTORIES_RESOURCE_LOCATION"
接下来的逻辑就很清晰了,包META-INF下获取spring.factories配置文件,读取配置并返回自动装配列表。
通过断点调试,笔者发现Springboot会从spring-boot.jar、spring-breans.jar、spring-boot-autoconfiguration三个包下的"META-INF/spring.factories"读取默认配置。同时我们也可以设想,将第三方starter加入springboot自动装配也是相同的道理,只要将自己的XXautoconfiguration类写到自己包"META-INF"路径下spring.factories文件中即可。
4.总结
- Spring Boot 在启动时除了扫描与启动类同一包下的组件之外,还会检查各个 jar 包中是否存在 META-INF/spring.factories 文件,为自动装配做准备。
- 第三方的 spring-boot-starter 会通过将自己的自动装配类写到 META-INF/spring.factories 中让Spring Boot加载到容器中,使自动装配类能够生效。