Spring源碼解析系列一:配置類的初始化過程

從今天開始,準備寫關於Spring源碼的博客,那麼廢話很少說, 我們開始搞!java

1.環境準備

1).看圖:spring

PersonService類:數組

@Component
public class PersonService {
	public void run(){
		System.out.println("run方法執行了");
	}
}
複製代碼

SpringConfiguration類:app

@ComponentScan("my.blog")
public class SpringConfiguration {

}
複製代碼

Test01類:ide

public class Test01 {
	public static void main(String[] args) {
		//這個構造方法會把Spring全部的環境都準備好
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
		PersonService person = ac.getBean(PersonService.class);
		person.run();
	}
}
複製代碼

2.介紹:註解配置應用上下文

AnnotationConfigApplicationContext 顧名思義:註解配置應用上下文, 我在演示當中使用的是註解的方式函數

因此須要 new AnnotationConfigApplicationContext 這個對象.ui

若是採用的是xml的配置方式 則須要 new ClassPathXmlApplicationContext ,這個應該我不用多說,我想你應該懂的!this

那麼這個實例化對象的過程,Spring到底中幹了哪些見不得人的事呢? 接下來跟着我一塊兒去揭開他的神祕面紗!lua

咱們點擊 new AnnotationConfigApplicationContext看一下他的構造方法:spa

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//這個類有父類,因此會先初始化父類的構造方法,接着初始化本身的構造方法

		//調用無參構造方法進行初始化一個讀取器和掃描儀
		this();
		
       //這個方法的做用:主要是把配置類的信息加載進工廠中
       //在這裏須要你記住一個類:DefaultListableBeanFactory,後面會很是的重要
		register(annotatedClasses);

		//實例化全部被加了組件的對象
		refresh();
	}

複製代碼

咱們發現這個構造函數的參數能夠一次性傳多個配置類,後面代碼中其實會遍歷annotatedClasses 這個數組

咱們看一下 this() 幹了哪些事?

public AnnotationConfigApplicationContext() {
		//這裏也會先初始化父類的構造方法
        
        //建立一個讀取被加了註解的bean讀取器 ,這個讀取器到底什麼鬼,不是這節的重點,能夠先忽略
        //你就知道他建立了一個讀取器就完事了
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
複製代碼

咱們回到 register(annotatedClasses);這個方法, 這個方法就是本節的大哥,咱們如今就要去看看,他爲Spring幹了哪些髒活!

3.加載配置類

咱們點擊 register(annotatedClasses)

嗯....,好像沒啥用!

點擊 this.reader.register(annotatedClasses); 方法

這時候,咱們發現這個方法開始遍歷annotatedClasses 數組,由此咱們能夠一次性寫多個配置文件傳給構造方法的

開始遍歷annotatedClasses(注意:本次演示中,我只添加了一個配置類), 調用 registerBean(annotatedClass);

咱們這時候點擊 registerBean(annotatedClass);

點擊 doRegisterBean(annotatedClass, null, null, null);

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
        //(1)(解析:查看下面圖)
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
	 
        
        //這個不是重點,跳過
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}
        
         //這個不是重點,跳過 instanceSupplier爲null值
		abd.setInstanceSupplier(instanceSupplier);

		//(2)獲得類的做用域 單例仍是多例(解析:查看下面圖)
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        
		//把類的做用域賦值給AnnotatedGenericBeanDefinition對象
		abd.setScope(scopeMetadata.getScopeName());

		//生成配置類的名稱,若是@Component沒有對應的名稱 (我沒有加名稱)
        //默認是類的小駝峯式命名稱 (全部此時beanName爲springConfiguration)
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

		/** * (3)把AnnotatedGenericBeanDefinition對象傳進 * 而後獲取獲取元數據metadata對象,判斷元數據對象中是否存在lazy,DependsOn,Primary Role 等註解 * 若是有這些註解,則在AnnotatedGenericBeanDefinition對象中記錄 */
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

		//qualifiers自己傳過來的就是一個 null 值
		//若是不手動傳,永遠爲空值,沒有意義
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
        
		//這個不是重點
		for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
			customizer.customize(abd);
		}
        
         //(4)把abd放進去,賦值給了成員變量beanDefinition
		//把BeanName賦值進去,能夠說是加強版的abd對象
		//查看後面的代碼發現,其實definitionHolder就只是起到一個臨時容器的做用
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

		//這個比較複雜,之後能夠講 和本節無關
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

		//(5)如今又把加強版的 definitionHolder 放到registry這個容器中
		//BeanDefinitionRegistry 顧名思義 就是註冊BeanDefinition的
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}
複製代碼

1).咱們查看代碼AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);幹了哪些事 ?

經過debug 查看 abd 對象內容

總結:

  1. 根據指定的配置類,建立一個GenericBeanDefinition對象
  2. 這個GenericBeanDefinition對象包含了該類的一些元信息,例如註解信息: scope,lazy,ComponentScan等註解
  3. 這些註解存儲在 GenericBeanDefinition中的 元數據(metadata)對象中
  4. 元數據對象有一個註解集合 annotations ,存儲全部的註解信息

2).接下來查看 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);

執行完這個abd.setScope(scopeMetadata.getScopeName());方法後

3).查看 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

點擊進入

額..., 這個方法好像也沒啥...

把傳進的abd對象拆開,又傳了abd對象和abd.getMetadata()元數據對象

點擊 processCommonDefinitionAnnotations(abd, abd.getMetadata());

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
		//判斷當前的類是否加了lazy註解
		AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
        
		//若是不爲null,則把AnnotatedBeanDefinition中的 lazyInit 默認的false 修改成true
		if (lazy != null) {
			abd.setLazyInit(lazy.getBoolean("value"));
		}
		else if (abd.getMetadata() != metadata) {
			lazy = attributesFor(abd.getMetadata(), Lazy.class);
			if (lazy != null) {
				abd.setLazyInit(lazy.getBoolean("value"));
			}
		}
        
		//判斷元數據對象中時候有@Primary,默認時候primary是 false ,若是有則該爲true
		if (metadata.isAnnotated(Primary.class.getName())) {
			abd.setPrimary(true);
		}
        
		//判斷時候有@DependsOn註解
		AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
		if (dependsOn != null) {
			abd.setDependsOn(dependsOn.getStringArray("value"));
		}

		//判斷時候有@Role註解
		AnnotationAttributes role = attributesFor(metadata, Role.class);
		if (role != null) {
			abd.setRole(role.getNumber("value").intValue());
		}
        
		//判斷時候有@Description註解
		AnnotationAttributes description = attributesFor(metadata, Description.class);
		if (description != null) {
			abd.setDescription(description.getString("value"));
		}
	}
複製代碼

總結:

  1. 把AnnotatedGenericBeanDefinition對象傳進去
  2. 獲取元數據metdata對象,判斷元數據對象中是否存在lazy,DependsOn,Primary Role 等註解
  3. 若是有這些註解,則在AnnotatedGenericBeanDefinition對象中記錄

4).查看 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

debug 發現

5).查看 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

點擊進入

public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {

		
		//在這裏又獲取beanName的名稱
		String beanName = definitionHolder.getBeanName();
    
		//如今把definitionHolder拆分了,又把abd對象拿出來了
		//彷佛definitionHolder就只是封裝了一下,而後又給拆分, 能夠理解爲一個臨時的容器
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		 //這個不重要,spring當中處理別名的
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}
複製代碼

咱們點擊 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

發現是一個接口, 按住快捷鍵 Ctrl + Alt + B ,有三個實現類,前面叫你留意的 DefaultListableBeanFactory 在這裏出現了,

選擇 DefaultListableBeanFactory

@Override
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
   //-------------------------------------------------------------------------------
		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");
     
		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
        //查看該bean時候在map集合中存儲過
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
     //---------------------------------------------------------------------------------------
            //前面的代碼都是一些判斷,驗證不是重點
            //重點是這裏的代碼,前方高能
			else {
				//在這個方法中就把 beanDefinition 存儲在 DefaultListableBeanFactory的map集合中
				//顧名思義,beanDefinitionMap就是一個存儲beanDefinition的map集合
				//在這個集合當中還有Spring當中自己已經初始好的對象
				this.beanDefinitionMap.put(beanName, beanDefinition);
				//把beanName存儲在這個list集合中
				this.beanDefinitionNames.add(beanName);
				//這個是去重的,不是重點
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}
複製代碼

this.beanDefinitionMap.put(beanName, beanDefinition); 以前

this.beanDefinitionMap.put(beanName, beanDefinition); 以後

this.beanDefinitionNames.add(beanName); 以前

this.beanDefinitionNames.add(beanName); 以後

整個配置類的加載過程就執行完了,最後總結一下 register(annotatedClasses); 都幹了哪些事?

  1. 加載配置類的元數據 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
  2. 給abd對象設置做用域
  3. 遍歷元數據註解 ,判斷時候存在某註解
  4. 把配置類信息對象存儲到 DefaultListableBeanFactory的beanDefinitionMap集合中
  5. 把配置類的名稱存儲到 DefaultListableBeanFactory的 beanDefinitionNames 集合中
相關文章
相關標籤/搜索