1. 程式人生 > 程式設計 >springboot如何實現自動裝配原始碼解讀

springboot如何實現自動裝配原始碼解讀

Spring Boot 自動裝配

最重要的註解@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

是實現自動裝配的核心註解

@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(
					// 載入配置元資料
					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";

注意: 這個檔案在target編譯後的資料夾中
自動裝配

spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories

該檔案記憶體有:

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:[email protected]: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;	

}

希望通過本篇對於springboot自動裝配的解讀,讓大家對springboot底層有了一個大致瞭解,只分析了主要方法,希望對大家有幫助

到此這篇關於springboot如何實現自動裝配原始碼賞析的文章就介紹到這了,更多相關springboot自動裝配內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!