自动配置
SpringBoot注解
@SpringBootApplication 主要由三个注解组成
-
@SpringBootConfiguration
表示一个类提供 Spring Boot 应用程序@Configuration 。可以用作 Spring 标准@Configuration注释的替代品,以便可以自动找到配置(例如在测试中)。
应用程序应该只包含一个@SpringBootConfiguration并且大多数惯用的 Spring Boot 应用程序将从@SpringBootApplication继承它。 -
@EnableAutoConfiguration
@AutoConfigurationPackage
使用AutoConfigurationPackages注册包。当没有指定base packages或base package classes时,通过工厂模式将@Configuration注解类注册。通俗的讲就是如果没有指定扫描的基础包,默认扫描注解标识的类所在包下的Java配置类。
@Import()
其中AutoConfigurationImportSelector这个类是ImportSelector接口的实现类,接口中的String[] selectImports(AnnotationMetadata importingClassMetadata);方法首先是否开启了自动配置,如果没有开启,返回一个空的数组,如果开启了则返回需要自动装配的配置类的全路径名的字符串数组。
@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { //判断是否开启自动配置 if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } //获取自动配置的配置类的键值对的对象,里面存放自动配置的配置类的全路径 AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); //返回需要交由容器管理的类的全限类名 return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); }
//获取自动配置的配置类的路径 protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } AnnotationAttributes attributes = getAttributes(annotationMetadata); //获取自动配置的配置类路径集合,读取META-INF/文件中属性的值 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); //去除重复的路径 configurations = removeDuplicates(configurations); //获取需要排除的自动配置的配置类路径集合 Set<String> exclusions = getExclusions(annotationMetadata, attributes); //检查配置类路径集合中是否存在需要排除的配置类路径,如果不存在,说明不需要从配置类路径集合中移除,相当于筛选出配置类路径集合中存在的配置类路径,然后进行移除 checkExcludedClasses(configurations, exclusions); //从配置类路径集合中移除需要排除的配置类路径 configurations.removeAll(exclusions); //获取条件过滤器,对配置类进行过滤,排除掉不满足条件的配置类,只留下满足条件的配置类 configurations = getConfigurationClassFilter().filter(configurations); fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry(configurations, exclusions); }
-
@ComponentScan
指定需要扫描的组件,具体参考注解的属性,可以指定基础包,也可以指定某个类所在的包
了解完@SpringBootApplication注解的组成,我们也可以模仿着写自定义的starter
步骤:
- 编写自动配置类
- 在META-INF目录下创建文件,并在里面添加属性=自动配置类的全限类名
- 当项目启动时,会扫描选择注册127个自动配置类到容器中,但只是注册,是否生效取决于它们是否满足条件和是否需要被排除
# Auto Configure
=\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
.neo4j.Neo4jDataAutoConfiguration,\
.neo4j.Neo4jReactiveDataAutoConfiguration,\
.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
.neo4j.Neo4jRepositoriesAutoConfiguration,\
.r2dbc.R2dbcDataAutoConfiguration,\
.r2dbc.R2dbcRepositoriesAutoConfiguration,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
.h2.H2ConsoleAutoConfiguration,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
.neo4j.Neo4jAutoConfiguration,\
,\
,\
,\
.r2dbc.R2dbcAutoConfiguration,\
.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
.saml2.Saml2RelyingPartyAutoConfiguration,\
,\
,\
..OAuth2ClientAutoConfiguration,\
..ReactiveOAuth2ClientAutoConfiguration,\
..OAuth2ResourceServerAutoConfiguration,\
..ReactiveOAuth2ResourceServerAutoConfiguration,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
,\
-
SpringBoot底层默认帮我们场景所需要的组件注册好
-
如果用户自己注册组件到容器中,则以用户的优先,否则就以默认配置帮我们注册到容器中
-
如果我们需要修改默认配置
- 自己通过@Bean注册到容器中,因为以用户注册的优先,如果用户注册了默认的就不会生效
- 通过配置文件进行修改,因为xxxautoConfiguration实际上是和配置类进行绑定,而配置类和配置文件进行绑定,所以我们只需要修改配置文件就可以了
-
关键注解: @Conditional
-
开启自动配置报告,在配置文件中 debug = true 即可在项目启动后在控制台打印自动配置报告,Negative(不生效的自动配置),Positive(生效的自动配置)