SpringBoot 自動裝配特性

一、理解 spring-boot-starter 自動裝配 

大家都知道使用 spring-boot-starter 可以簡化日常開放中的配置,那麼大家是否好奇,這些簡化的配置SpringBoot是怎麼爲我們的應用自動裝配的呢?帶着疑問,一起來看看SpringBoot的自動裝配功能吧。 

  1. 理解 @SpringBootApplication 啓動類註解

1.1 @SpringBootApplication 由以下三個關鍵註解組成 

@SpringBootConfiguration // 該註解與 @Configuration 無異
@ComponentScan // 該註解用於激活註解掃描
@EnableAutoConfiguration // 該註解用於激活自動裝配

@EnableAutoConfiguration  

激活自動裝配註解代碼如下:


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

@EnableAutoConfiguration註解中使用 @Import({AutoConfigurationImportSelector.class}) ,導入了AutoConfigurationImportSelector類。

由於AutoConfigurationImportSelector  是 ImportSelector 接口的子類,所以直接看 AutoConfigurationImportSelector#selectImports() ,如下:

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {


    @Override
	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());
	}

}

繼續往下看 getAutoConfigurationEntry 方法是如何實現的

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
        // 獲取屬性
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 獲取準備裝配的配置類集合	
        List<String> configurations = 
              getCandidateConfigurations(annotationMetadata, attributes);
        // 去重操作
        configurations = removeDuplicates(configurations);
        // 獲取排除的配置類
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
        // 從待裝配的配置類集合中去除待排除的配置類
        configurations.removeAll(exclusions);
        // 再次過濾
		configurations = filter(configurations, autoConfigurationMetadata);
        // 發佈自動裝配事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
}

獲取準備裝配的配置類集合   getCandidateConfigurations() 方法實現

  大家可以看到,重點是獲取準備裝配的配置類集合方法 getCandidateConfigurations() 進一步往下看會看到,程序會去加載根目錄下的 META-INF/spring.factories 文件,META-INF/spring.factories 如下所示:

可以看到 META-INF/spring.factories  是一個properties文件,其中 

org.springframework.boot.autoconfigure.EnableAutoConfiguration

對應的value則是SpringBoot自動裝配的配置類,包括我們常見的數據庫自動裝配  DataSourceAutoConfiguration和RedisAutoConfiguration自動裝配等。這樣就可以做到我們在application.properties文件中只需配置數據庫與redis的連接信息就可以使用了。

二、自定義開發 spring-boot-starter 

1、新建項目customer-spring-boot-starter  

  • 添加一個  CustomerAutoConfiguration 配置類,並註冊一個 String 類型的bean

 

  • 在根目錄下新建 /META-INF/spring.factories文件,並配置上一步的新增的配置類 CustomerAutoConfiguration

 

2、新建一個測試項目 test 並在pom文件中引用 customer-spring-boot-starter

可以看到控制檯輸入的張三,就是我們自動裝配的bean,自定義開發Spring-boot-starter就是這麼簡單 !

源碼地址:https://github.com/yuhuangbin/spring-boot-starter-sample 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章