SpringBoot中@EnableAutoConfiguration和@Configuration的區(qū)別
@EnableAutoConfiguration 注解 和 @Configuration注解的區(qū)別
在Spring Boot中,我們會(huì)使用@SpringBootApplication來開啟Spring Boot程序。
在之前的文章中我們講到了@SpringBootApplication相當(dāng)于@EnableAutoConfiguration,@ComponentScan,@Configuration三者的集合。
其中@Configuration用在類上面,表明這個(gè)是個(gè)配置類,如下所示:
@Configuration
public class MySQLAutoconfiguration {
...
}而@EnableAutoConfiguration則是開啟Spring Boot的自動(dòng)配置功能。
什么是自動(dòng)配置功能呢?
簡單點(diǎn)說就是Spring Boot根據(jù)依賴中的jar包,自動(dòng)選擇實(shí)例化某些配置。
接下來我們看一下@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ì)從類加載器中查找所有的META-INF/spring.factories,并加載其中實(shí)現(xiàn)了@EnableAutoConfiguration的類。
有興趣的朋友可以具體研究一下這個(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*** 的注解,這種注解的作用就是判斷該配置類在什么時(shí)候能夠起作用。
到此這篇關(guān)于SpringBoot中@EnableAutoConfiguration和@Configuration的區(qū)別的文章就介紹到這了,更多相關(guān)@EnableAutoConfiguration和@Configuration內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis使用update更新值為null時(shí)不生效問題解決
這篇文章主要介紹了Mybatis使用update更新值為null時(shí)不生效問題解決,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
PageHelper引發(fā)的幽靈數(shù)據(jù)問題解析
這篇文章主要為大家介紹了PageHelper引發(fā)的幽靈數(shù)據(jù)問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
Java實(shí)現(xiàn)線性表的順序存儲(chǔ)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)線性表的順序存儲(chǔ),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10
Spring Hibernate實(shí)現(xiàn)分頁功能
這篇文章主要為大家詳細(xì)介紹了Spring Hibernate實(shí)現(xiàn)分頁功能的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05

