springboot如何實(shí)現(xiàn)自動(dòng)裝配源碼解讀
Spring Boot 自動(dòng)裝配
最重要的注解@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 {
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
EnableAutoConfiguration
是實(shí)現(xiàn)自動(dòng)裝配的核心注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
getAutoConfigurationMetadata()
@Override
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
() -> String.format("Only %s implementations are supported, got %s",
AutoConfigurationImportSelector.class.getSimpleName(),
deferredImportSelector.getClass().getName()));
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
.getAutoConfigurationEntry(
// 加載配置元數(shù)據(jù)
getAutoConfigurationMetadata(), annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
private AutoConfigurationMetadata getAutoConfigurationMetadata() {
if (this.autoConfigurationMetadata == null) {
// 加載配置信息
this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
}
return this.autoConfigurationMetadata;
}
static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader, String path) {
try {
// 獲取資源路徑
Enumeration<URL> urls = (classLoader != null) ? classLoader.getResources(path)
: ClassLoader.getSystemResources(path);
Properties properties = new Properties();
while (urls.hasMoreElements()) {
properties.putAll(PropertiesLoaderUtils.loadProperties(new UrlResource(urls.nextElement())));
}
return loadMetadata(properties);
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load @ConditionalOnClass location [" + path + "]", ex);
}
}
protected static final String PATH = "META-INF/spring-autoconfigure-metadata.properties";
注意: 這個(gè)文件在target編譯后的文件夾中
自動(dòng)裝配
spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
該文件內(nèi)存有:
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,\
EnableConfigurationProperties
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
/**
* Database index used by the connection factory.
*/
private int database = 0;
/**
* Connection URL. Overrides host, port, and password. User is ignored. Example:
* redis://user:password@example.com:6379
*/
private String url;
/**
* Redis server host.
*/
private String host = "localhost";
/**
* Login password of the redis server.
*/
private String password;
/**
* Redis server port.
*/
private int port = 6379;
/**
* Whether to enable SSL support.
*/
private boolean ssl;
/**
* Connection timeout.
*/
private Duration timeout;
/**
* Client name to be set on connections with CLIENT SETNAME.
*/
private String clientName;
}
希望通過(guò)本篇對(duì)于springboot自動(dòng)裝配的解讀,讓大家對(duì)springboot底層有了一個(gè)大致了解,只分析了主要方法,希望對(duì)大家有幫助
到此這篇關(guān)于springboot如何實(shí)現(xiàn)自動(dòng)裝配源碼賞析的文章就介紹到這了,更多相關(guān)springboot自動(dòng)裝配內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java System.currentTimeMillis()時(shí)間的單位轉(zhuǎn)換與計(jì)算方式案例詳解
這篇文章主要介紹了Java System.currentTimeMillis()時(shí)間的單位轉(zhuǎn)換與計(jì)算方式案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
詳解java連接mysql數(shù)據(jù)庫(kù)的五種方式
這篇文章主要介紹了詳解java連接mysql數(shù)據(jù)庫(kù)的五種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑
這篇文章主要介紹了解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
SpringBoot+Shiro+LayUI權(quán)限管理系統(tǒng)項(xiàng)目源碼
本項(xiàng)目旨在打造一個(gè)基于RBAC架構(gòu)模式的通用的、并不復(fù)雜但易用的權(quán)限管理系統(tǒng),通過(guò)SpringBoot+Shiro+LayUI權(quán)限管理系統(tǒng)項(xiàng)目可以更好的幫助我們掌握springboot知識(shí)點(diǎn),感興趣的朋友一起看看吧2021-04-04

