1. 程式人生 > 程式設計 >Spring原始碼解析系列二:Spring初始化準備處理器過程

Spring原始碼解析系列二:Spring初始化準備處理器過程

今天是Spring系列的第二篇文章,加油!

1.建立一個測試類

public class Test01 {
	public static void main(String[] args) {
		//這個構造方法會把Spring所有的環境都準備好
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
	}
}
複製程式碼

2.點選 AnnotationConfigApplicationContext

	public AnnotationConfigApplicationContext
(Class<?>... annotatedClasses)
{ //這個類有父類,所以會先初始化父類的構造方法,接著初始化自己的構造方法 //呼叫無參構造方法進行初始化一個讀取器和掃描器 this(); //把配置類載入進 DefaultListableBeanFactory 的map集合中 //配置類可以一次性傳多個,這個方法執行後,只是把配置類載入進了 DefaultListAbleBeanFactory的map集合中 //還沒有掃描其他的的加了元件的類 register(annotatedClasses); //例項化所有被加了元件的物件 refresh(); } 複製程式碼

初始化 AnnotationConfigApplicationContext 這個類之前會首先初始化話其父類,

AnnotationConfigApplicationContext ` 的父類為 GenericApplicationContext

3.檢視 GenericApplicationContext

public GenericApplicationContext() {
   //例項化工廠
   this.beanFactory = new DefaultListableBeanFactory();
}
複製程式碼

DefaultListableBeanFactory 就是我們的 Bean工廠類

通過檢視 GenericApplicationContext的預設構造方法發現,我們的神奇的Bean工廠是在這裡被初始化的

4.回到 AnnotationConfigApplicationContext

	public AnnotationConfigApplicationContext() {
		//建立一個讀取被加了註解的bean讀取器,當前物件傳過去
		this.reader = new AnnotatedBeanDefinitionReader(this);
		/**
		 * 可以用來掃描包來轉換成beanDefinition
		 * 但是Spring掃描包不是使用這個物件,而是使用ClassPathBeanDefinitionScanner
		 * 這裡的scanner僅僅是為了使用者之間能夠使用 AnnotationConfigApplicationContext物件的scan()方法
		 * 如果使用者沒有自己手動呼叫的話,其實是沒有掃描作用的
		 */
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
複製程式碼

檢視 AnnotationConfigApplicationContext預設的構造方法,初始化了讀取器 AnnotatedBeanDefinitionReader,準備處理器的功能就在這個類中,至於 ClassPathBeanDefinitionScanner對於註解開發來說,似乎沒有什麼作用.

5.點選 AnnotatedBeanDefinitionReader

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
		this(registry,getOrCreateEnvironment(registry));
	}
複製程式碼

這裡沒有做什麼,呼叫另一個構造方法 通過引數BeanDefinitionRegistry,我們可以發現 AnnotationConfigApplicationContext物件,其實就是一個註冊器 此時的registry實質就是AnnotationConfigApplicationContext物件

6.點選 this

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry,Environment environment) {
		Assert.notNull(registry,"BeanDefinitionRegistry must not be null");
		Assert.notNull(environment,"Environment must not be null");
		//把AnnotationConfigApplicationContext物件賦值給當前類的 registry
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry,environment,null);
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
複製程式碼

7.點選 registerAnnotationConfigProcessors

	public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
		//同樣的構造方法名,引數列表不一樣
		registerAnnotationConfigProcessors(registry,null);
	}
複製程式碼

8.點選 registerAnnotationConfigProcessors

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry,@Nullable Object source) {

		//通過registry,獲取beanFactory工廠物件
		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
				//新增排序物件 AnnotationAwareOrderComparator
				if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
					beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
				}
			//提供延遲載入的功能ContextAnnotationAutowireCandidateResolver
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}
         //BeanDefinitionHolder 裡面有一個beanName 和 beanDefinition 屬性方便傳引數
		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		/**
		 * 問個問題?為啥要註冊這個ConfigurationClassPostProcessor類到工廠的map集合中呢?
		 * 以後文章解析!
		 */

     //判斷整個環境中時候存在了這個常量
    //org.springframework.context.annotation.internalConfigurationAnnotationProcessor
	//CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME 會被作為beanName
    
      //(1)把處理 ConfigurationClassPostProcessor的描述類 新增進 工廠
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry,def,CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

       //(2)把處理 AutowiredAnnotationBeanPostProcessor 的描述類 新增進 工廠
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry,AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry,COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

      //(3)把處理 CommonAnnotationBeanPostProcessor 的描述類 新增進 工廠
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry,PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

      //(4)把處理 EventListenerMethodProcessor 的描述類 新增進 工廠
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry,EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

      //(5)把處理 DefaultEventListenerFactory 的描述類 新增進 工廠
		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry,EVENT_LISTENER_FACTORY_BEAN_NAME));
		}
    
         //在reader這個過程當中,這個返回值不會起任何作用
		return beanDefs;
	}
複製程式碼

9.點選 registerPostProcessor方法

	private static BeanDefinitionHolder registerPostProcessor(
			BeanDefinitionRegistry registry,RootBeanDefinition definition,String beanName) {
       //ROLE_INFRASTRUCTURE=2 代表是Spring內部的類,ROLE_SUPPORT = 1;代表的是使用者的類
		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

		//此時的beanName為就是Spring自己定義的常量字串
		//這個方法就是把  內部類definition儲存到 beanDefinitionMap中
		registry.registerBeanDefinition(beanName,definition);
		return new BeanDefinitionHolder(definition,beanName);
	}
複製程式碼

10.Ctrl+Alt+B 點選 registerBeanDefinition

我們選擇 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);
			}
		}

		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName,beanDefinition,existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				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()) {
				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);中把 處理器的描述類新增進 beanDefinitionMap集合中

到了這裡Spring 就把需要的處理器新增進Spring工廠啦

視訊講解:

www.bilibili.com/video/av678…

視訊為自己學習的時候錄製的,也方便自己以後看

Spring5原始碼地址:

github.com/zouchangfu/… gitee.com/zouchangfu/…

Spring5原始碼都是已經構建好的了,無需再使用gradle進行構建了,直接開啟就可以跑起來

寫在最後:

大二學生一枚,擠時間寫部落格不容易,看完順手點個贊,你的點贊是對我最大的鼓勵