SpringBoot自動配置原理源碼級別分析


SpringBoot自動配置原理

前言

后面還會講到SpringBoot自動配置原理,會主要講解@EnableAutoConfiguratuon注解幫助我們做了什么事情,是如何自動把自動配置類掃描到容器中的,建議看完這篇后,兩篇配合使用,傳送門

package com.staticzz.springboot_quick;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
**@SpringBootApplication注解為核心注解
**
**/
@SpringBootApplication
public class SpringbootQuickApplication {

    public static void main(String[] args) {

        SpringApplication.run(SpringbootQuickApplication.class, args);
    }

}

SpringBootApplication注解作用

@SpringBootApplication 標注在某一個類上,就說明這個類為SpringBoot應用的主配置類,SpringBoot就應該運行這個類的main方法來啟動Springboot應用

以前我們開發一個SSM項目,需要利用配置文件進行相關配置,而SpingBoot利用了配置類進行自動配置,

這里配置類等同於配置文件,SpringBoot並且開啟了自動配置,以前我們需要手動配置的東西

這里SpringBoot幫我們進行了自動配置

PS: 自動配置原理也是SpringBoot的精髓所在

package com.staticzz.springboot_quick;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
@SpringBootApplication注解標注在某一個類上,
就說明這個類為SpringBoot應用的主程序類
SpringBoot就應該運行這個類的main方法來啟動Springboot應用
**/
@SpringBootApplication
public class SpringbootQuickApplication {

    public static void main(String[] args) {

        SpringApplication.run(SpringbootQuickApplication.class, args);
    }
}

那@SpringBootApplication 這個注解與自動配置又有什么關系呢?
接下來我們Ctrl+左鍵,進入到這個注解中來查看 @SpringBootApplication 這個注解里到底配置了什么?我們先來進入到@SpringBootApplication這個注解中,看看它底層調用了什么注解

動圖演示:

image

我們觀察到 @SpringBootApplication注解 繼承了 @SpringBootConfiguration注解 ,而 @SpringBootConfiguration注解 又繼承了Spring底層的注解 @Configuration注解 , 凡是標注該注解的類都是配置類

那現在也只是知道了 @SpringBootApplication注解 一層一層的實現了Spring底層的 @Configuration注解 ,被標注后稱為配置類!那說了這篇文章講的是SpringBoot的自動配置?配置有了,自動呢?

image

我沒有騙人哦!確實是有自動配置的!而且SpringBoot也確確實實幫我們做了自動配置

image

先上一張動態演示圖,瞧瞧

image

第一步 ctrl+右鍵 進入了 @EnableAutoConfiguration 這個注解

@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited

/**
**這個注解為自動導包的注解
**/
@AutoConfigurationPackage

/**
**這個為開啟自動配置選擇器的注解
**/
@Import(EnableAutoConfigurationImportSelector.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 {};

}

有沒有發現我在這動態演示中,重點高亮了兩個注解

@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)

這兩個注解分別是什么意思 廢話不多說 下面看!

@AutoConfigurationPackage 自動掃描包

@Import(EnableAutoConfigurationImportSelector.class) 導入自動配置類選擇器組件

來看源碼分析
@AutoConfigurationPackage

源碼展示:

/**
* {@link ImportBeanDefinitionRegistrar} to store the base package from the importing
* configuration.
*/
@Order(Ordered.HIGHEST_PRECEDENCE)
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

   //這個方法為SpringBoot幫助我們自動掃描包獲取獲取包名並進行注冊
   @Override
   public void registerBeanDefinitions(AnnotationMetadata metadata,
   BeanDefinitionRegistry registry) {
        register(registry, new PackageImport(metadata).getPackageName());
     	}
		
    
	@Override
    public Set<Object> determineImports(AnnotationMetadata metadata) {
		return Collections.<Object>singleton(new PackageImport(metadata));
		}
	}

動態展示 自動掃描包

注意觀察動圖中我高亮的部分

image

結論:SpringBoot在啟動時,會自動掃描主程序類所在的包下的所有子包

來看源碼分析
@Import(EnableAutoConfigurationImportSelector.class)

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
	if (!isEnabled(annotationMetadata)) {
		return NO_IMPORTS;
	}
	try {
     AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
					.loadMetadata(this.beanClassLoader);
			
			//獲取到注解元數據		
			AnnotationAttributes attributes = getAttributes(annotationMetadata);
            //獲取到配置類封裝為一個list數據
			List<String> configurations = getCandidateConfigurations(annotationMetadata,
					attributes);
			configurations = removeDuplicates(configurations);
			configurations = sort(configurations, autoConfigurationMetadata);
			Set<String> exclusions = getExclusions(annotationMetadata, attributes);
			checkExcludedClasses(configurations, exclusions);
			configurations.removeAll(exclusions);
			configurations = filter(configurations, autoConfigurationMetadata);
			fireAutoConfigurationImportEvents(configurations, exclusions);
			
			//返回給容器
			return configurations.toArray(new String[configurations.size()]);
		}
		catch (IOException ex) {
			throw new IllegalStateException(ex);
		}
	}

@Import(EnableAutoConfigurationImportSelector.class) 這個注解的作用選擇自動配置類並掃描進容器中,

動態展示 導入自動配置類選擇器組件
image

總結: SpringBoot給容器中導入非常多的自動配置類(xxxAutoConfiguration),就是給容器中導入場景所需要的所有組件並自動配置好這些組件**


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM