什么是自动装配
没有 Spring Boot 的情况下,如果我们需要引入第三方依赖,需要手动配置,非常麻烦。但是,Spring Boot 中,我们直接引入一个 starter 即可。
通过注解或者一些简单的配置就能在 Spring Boot 的帮助下实现某块功能。自动装配是 Spring Boot 的核心
@SpringBootApplication注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
......
}
@SpringBootApplication注解可以看做是 @Configuration, @EnableAutoConfiguration, @ComponentScan 注解的集合
- @EnableAutoConfiguration: 启用SpringBoot的自动配置机制
- @ComponentScan: 扫描被@Component注解的bean,注解默认会扫描该类所在的包下所有的类
- @Configuration: 允许在上下文中注册额外的bean或导入其他配置类
SpringBoot的自动配置原理
@SpringBootApplication注解中的@EnableAutoConfiguration注解是启动自动配置的关键
@EnableAutoConfiguration注解作用
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};
}
@EnableAutoConfiguration 注解中主要使用了@Import注解导入了AutoConfigurationImportSelector类
进入 AutoConfigurationImportSelector 类,查看
selectImports(AnnotationMetadata annotationMetadata)方法,这个方法主要作用就是批量将类注入到IOC容器中
在getAutoConfigurationEntry(AnnotationMetadata annotationMetadata)中通过getCandidateConfigurations方法来获取候选配置,然后对候选配置进行去除,排除特定类,校验过滤等操作获取最终配置,最后触发自动配置事件对这些组件进行配件
在getCandidateConfigurations获取候选配置方法中,调用的是SpringFactoriesLoader类的loadFactoryNames方法.
主要功能就是从指定的配置文件 META-INF/spring.factories中根据 EnableAutoConfiguration 的全限定类名获取到需要导入的类
在META-INF/spring.factories文件中EnableAutoConfiguration 下有如此多的类,如何判定哪些类生效呢?
以WebMvcAutoConfiguration为例:
在该类中有@ConditionalOnWebApplication(type = Type.SERVLET)注解,其作用是判定当前应用是否是一个web应用.
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
作用是判定是否有加载Servlet,DispatcherServlet和WebMvcConfigurer类
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
作用是判断是否没有加载WebMvcConfigurationSupport类
当三个条件达成时,则配置该类
总结
- 利用EnableAutoConfigurationImporSelector给容器导入一些组件
- 将类路径下的spring.factories里的所有EnableAutoConfiguration的值加入容器中
- 每一个自动配置类进行自动配置功能
a. @ConfigurationProperties注解绑定对应的配置文件
b. xxxAutoConfiguration自动配置类
c. 内部根据@ConditionOnXXX注解来做各种条件判断这个类中的配置是否生效
d. 一旦这个配置类生效了,这个配置类就给容器中添加各种组件,这些组件的属性是从对应的properties类中获取的,这个类的每一个属性和配置文件绑定
- Springboot启动会加载大量的自动配置类
- 看需要的功能是不是有springboot写好的自动配置类
- 再看这个自动配置类中到底配置了什么(有需要的组件就不需要再来配置了)
- 给容器中自动配置类添加组件的时候,会从properties类中获取相应的属性,这样就可以在配置文件总值的这些属性的值
@Condition注解提供更佳灵活的条件判断
- 在类路径中是否存在这一的一个类
- 在Spring容器中是否已经注册了某种类型的Bean,如果没有,就可以让其自动注册
- 一个文件是否在特定的位置上
- 一个特定的系统属性是否存在
- 在Spring的配置文件中是否设置了某个特定的值