@EnableAutoConfiguration
SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration
在spring中有关于 @Enablexxx
的注解是开启某一项功能的注解,比如 @EnableScheduling
表示开启spring的定时任务。其原理是借助 @Import
的帮助,将所有符合自动配置条件的bean定义加载到Ioc容器。
1 | (ElementType.TYPE) |
从源码中可以知道,最关键的要属 @Import(EnableAutoConfigurationImportSelector.class)
,借助EnableAutoConfigurationImportSelector
,@EnableAutoConfiguration
可以帮助SpringBoot应用将所有符合条件的 @Configuration
配置都加载到当前SpringBoot创建并使用的IoC容器。
同时借助于 Spring 框架原有的一个工具类:SpringFactoriesLoader,@EnableAutoConfiguration
就可以实现智能的自动配置。
@EnableAutoConfiguration
作用就是从classpath中搜寻所有的 META-INF/spring.factories 配置文件将其中 org.springframework.boot.autoconfigure.EnableutoConfiguration 对应的配置项通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。
这些功能配置类要生效的话,会去classpath中找是否有该类的依赖类,所以功能类能生效需要的条件:
- spring.factories里面有这个类的配置类(一个配置类可以创建多个围绕该功能的依赖类)
- pom.xml里面需要有对应的jar包
以Redis自动装配为例
从spring-boot-autoconfigure.jar/META-INF/spring.factories中获取redis的相关配置类全限定名(有120多个的配置类)RedisAutoConfiguration
RedisAutoConfiguration配置类生效的一个条件是在classpath路径下有RedisOperations类存在,因此springboot的自动装配机制会会去classpath下去查找对应的class文件。 其中
@ConditionalOnClass
注解是关键。
1 |
|
- 如果pom.xml有对应的jar包,就能匹配到对应依赖class
1 | <dependency> |
- 匹配成功,这个功能配置类才会生效,同时会注入默认的属性配置类 @EnableConfigurationProperties(RedisProperties.class)
1 | "spring.redis") (prefix = |
- Redis功能配置里面会根据条件生成最终的JedisConnectionFactory、RedisTemplate,并提供了默认的配置形式@ConditionalOnMissingBean(name = “redisTemplate”)
1 |
|
总结
容器在启动的时候Application.run,会调用EnableAutoConfigurationImportSelector.class的selectImports方法(其实是其父类的方法)
selectImports方法最终会调用SpringFactoriesLoader.loadFactoryNames方法来获取一个全面的常用BeanConfiguration列表
loadFactoryNames方法会读取 FACTORIES_RESOURCE_LOCATION(也就是spring-boot-autoconfigure.jar 下面的spring.factories),获取到所有的Spring相关的Bean的全限定名ClassName,大概120多个
selectImports 方法继续调用 filter(configurations, autoConfigurationMetadata);这个时候会根据这些BeanConfiguration里面的条件,来一一筛选,最关键的是 @ConditionalOnClass,这个条件注解会去classpath下查找,jar包里面是否有这个条件依赖类,所以必须有了相应的jar包,才有这些依赖类,才会生成IOC环境需要的一些默认配置Bean
最后把符合条件的BeanConfiguration注入默认的EnableConfigurationPropertie类里面的属性值,并且注入到IOC环境当中