javascript
Spring Boot @EnableAutoConfiguration和 @Configuration的区别
Spring Boot @EnableAutoConfiguration和
@Configuration的區(qū)別
在Spring Boot中,我們會(huì)使用@SpringBootApplication來(lái)開(kāi)啟Spring Boot程序。在之前的文章中我們講到了@SpringBootApplication相當(dāng)于@EnableAutoConfiguration,@ComponentScan,@Configuration三者的集合。
其中@Configuration用在類(lèi)上面,表明這個(gè)是個(gè)配置類(lèi),如下所示:
@Configuration public class MySQLAutoconfiguration {... }而@EnableAutoConfiguration則是開(kāi)啟Spring Boot的自動(dòng)配置功能。什么是自動(dòng)配置功能呢?簡(jiǎn)單點(diǎn)說(shuō)就是Spring Boot根據(jù)依賴(lài)中的jar包,自動(dòng)選擇實(shí)例化某些配置。
接下來(lái)我們看一下@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 {};}注意這一行: @Import(AutoConfigurationImportSelector.class)
AutoConfigurationImportSelector實(shí)現(xiàn)了ImportSelector接口,并會(huì)在實(shí)例化時(shí)調(diào)用selectImports。下面是其方法:
public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}這個(gè)方法中的getCandidateConfigurations會(huì)從類(lèi)加載器中查找所有的META-INF/spring.factories,并加載其中實(shí)現(xiàn)了@EnableAutoConfiguration的類(lèi)。 有興趣的朋友可以具體研究一下這個(gè)方法的實(shí)現(xiàn)。
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {MultiValueMap<String, String> result = cache.get(classLoader);if (result != null) {return result;}try {Enumeration<URL> urls = (classLoader != null ?classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));result = new LinkedMultiValueMap<>();while (urls.hasMoreElements()) {URL url = urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);for (Map.Entry<?, ?> entry : properties.entrySet()) {String factoryTypeName = ((String) entry.getKey()).trim();for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {result.add(factoryTypeName, factoryImplementationName.trim());}}}cache.put(classLoader, result);return result;}catch (IOException ex) {throw new IllegalArgumentException("Unable to load factories from location [" +FACTORIES_RESOURCE_LOCATION + "]", ex);}}我們?cè)倏匆幌聅pring-boot-autoconfigure-2.2.2.RELEASE.jar中的META-INF/spring.factories。
spring.factories里面的內(nèi)容是key=value形式的,我們重點(diǎn)關(guān)注一下EnableAutoConfiguration:
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\ org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\ ...這里只列出了一部分內(nèi)容,根據(jù)上面的代碼, 所有的EnableAutoConfiguration的實(shí)現(xiàn)都會(huì)被自動(dòng)加載。這就是自動(dòng)加載的原理了。
如果我們仔細(xì)去看具體的實(shí)現(xiàn):
@Configuration(proxyBeanMethods = false) @AutoConfigureAfter(JmxAutoConfiguration.class) @ConditionalOnProperty(prefix = "spring.application.admin", value = "enabled", havingValue = "true",matchIfMissing = false) public class SpringApplicationAdminJmxAutoConfiguration {可以看到里面使用了很多@Conditional*** 的注解,這種注解的作用就是判斷該配置類(lèi)在什么時(shí)候能夠起作用。
更多精彩內(nèi)容且看:
- 區(qū)塊鏈從入門(mén)到放棄系列教程-涵蓋密碼學(xué),超級(jí)賬本,以太坊,Libra,比特幣等持續(xù)更新
- Spring Boot 2.X系列教程:七天從無(wú)到有掌握Spring Boot-持續(xù)更新
- Spring 5.X系列教程:滿(mǎn)足你對(duì)Spring5的一切想象-持續(xù)更新
- java程序員從小工到專(zhuān)家成神之路(2020版)-持續(xù)更新中,附詳細(xì)文章教程
更多教程請(qǐng)參考 flydean的博客
總結(jié)
以上是生活随笔為你收集整理的Spring Boot @EnableAutoConfiguration和 @Configuration的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Scala的Higher-Kinded类
- 下一篇: 自定义spring boot的自动配置