SpringBoot中@EnableAutoConfiguration和@Configuration的區(qū)別
@EnableAutoConfiguration 注解 和 @Configuration注解的區(qū)別
在Spring Boot中,我們會使用@SpringBootApplication來開啟Spring Boot程序。
在之前的文章中我們講到了@SpringBootApplication相當于@EnableAutoConfiguration,@ComponentScan,@Configuration三者的集合。
其中@Configuration用在類上面,表明這個是個配置類,如下所示:
@Configuration public class MySQLAutoconfiguration { ... }
而@EnableAutoConfiguration則是開啟Spring Boot的自動配置功能。
什么是自動配置功能呢?
簡單點說就是Spring Boot根據(jù)依賴中的jar包,自動選擇實例化某些配置。
接下來我們看一下@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實現(xiàn)了ImportSelector接口,并會在實例化時調(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()); }
這個方法中的getCandidateConfigurations會從類加載器中查找所有的META-INF/spring.factories,并加載其中實現(xiàn)了@EnableAutoConfiguration的類。
有興趣的朋友可以具體研究一下這個方法的實現(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); } }
我們再看一下spring-boot-autoconfigure-2.2.2.RELEASE.jar中的META-INF/spring.factories。
spring.factories里面的內(nèi)容是key=value形式的,我們重點關(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的實現(xiàn)都會被自動加載。這就是自動加載的原理了。
如果我們仔細去看具體的實現(xiàn):
@Configuration(proxyBeanMethods = false) @AutoConfigureAfter(JmxAutoConfiguration.class) @ConditionalOnProperty(prefix = "spring.application.admin", value = "enabled", havingValue = "true", matchIfMissing = false) public class SpringApplicationAdminJmxAutoConfiguration {
可以看到里面使用了很多@Conditional*** 的注解,這種注解的作用就是判斷該配置類在什么時候能夠起作用。
到此這篇關(guān)于SpringBoot中@EnableAutoConfiguration和@Configuration的區(qū)別的文章就介紹到這了,更多相關(guān)@EnableAutoConfiguration和@Configuration內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Springboot自定義轉(zhuǎn)換器實現(xiàn)參數(shù)去空格功能
這篇文章主要介紹了使用Springboot自定義轉(zhuǎn)換器實現(xiàn)參數(shù)去空格功能,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08SpringBoot開發(fā)項目,引入JPA找不到findOne方法的解決
這篇文章主要介紹了SpringBoot開發(fā)項目,引入JPA找不到findOne方法的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11idea啟動報錯:Command line is too long問題
在使用IDEA時,若遇到"Commandlineistoolong"錯誤,通常是因為命令行長度超限,這是因為IDEA通過命令行或文件將classpath傳遞至JVM,操作系統(tǒng)對命令行長度有限制,解決方法是切換至動態(tài)類路徑,通過修改項目的workspace.xml文件2024-09-09PowerJob的DispatchStrategy方法工作流程源碼解讀
這篇文章主要為大家介紹了PowerJob的DispatchStrategy方法工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01