Spring源碼深度解析(八)——Spring環境的準備化工作

準備就包括了prepareRefresh(),obtainFreshBeanFactory()和prepareBeanFactory(beanFactory)。下面就逐個向下分析

prepareRefresh()

主要是對容器的激活標記的設置,啓動時間,驗證環境還有初始化一個用於對消息事件的提前發佈的Set,代碼及其註釋如下

/**
	 * Prepare this context for refreshing, setting its startup date and
	 * active flag as well as performing any initialization of property sources.
	 */
	protected void prepareRefresh() {
		// Switch to active.
		//激活容器,並設置當前時間爲啓動時間
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			} else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		//空方法,不做任何事情
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		//獲取當前環境並驗證被標記的都是可以解析的
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		// 初始化監聽器,準備階段是空,不是空就清空
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		} else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		// 用於對消息事件的提前發佈,爲空
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

這個方法相對還是比較簡單了,下面就來簡單的代碼調試一下
可以看到在環境這裏不改變的話是採用默認環境
在這裏插入圖片描述
可以看到初始的提前事件監聽器爲空
在這裏插入圖片描述

obtainFreshBeanFactory()

這個是獲取在AnnotationContextApplicationContext中傳入的BeanFactory,默認是DefaultListableBeanFactory。
可以從調試信息看到結果
在這裏插入圖片描述

prepareBeanFactory(beanFactory)

在上面得到BeanFactory後,現在就要對BeanFactory進行一些必要的設置以保證BeanFactory能正常運行,比如類加載器,Bean表達式解析器,Property資源編輯器,ApplicationContext的Bean後置處理器(可以對ApplicationContext進行擴展的),還有對一些內部接口類型的忽略,還有對一些的替換和對系統默認環境的註冊。
代碼如下

/**
	 * Configure the factory's standard context characteristics,
	 * such as the context's ClassLoader and post-processors.
	 *
	 * @param beanFactory the BeanFactory to configure
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {

		// Tell the internal bean factory to use the context's class loader etc.
		//告訴內部bean工廠使用上下文類加載器
		beanFactory.setBeanClassLoader(getClassLoader());
		//添加bean的表達式解析器,使beanFactory可以識別bean表達式
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//添加property資源編輯器註冊器
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
		// Configure the bean factory with context callbacks.
		//添加Spring  bean的後置處理器   ApplicationContext的後置處理器
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));


		//一個類實現下面這些接口的時候不會被自動注入
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		//如beanFactory這些類沒有在工廠中,在此進行註冊    依賴替換,如果需要BeanFactory就把beanFactory作爲替換
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// 註冊事件監聽器    如果這個Bean是ApplicationListener的子類,將它添加到listener列表
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		//加載時織入(不同於AOP這是靜態的)
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		//如果自定義的Bean中沒有名字爲“systemProperties”和“systemEnvironment”的Bean
		//key爲“systemProperties”和“systemEnvironment”  value爲存系統信息和系統環境配置的Map
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

可以看到準備完成的BeanFactory
在這裏插入圖片描述
在這裏插入圖片描述

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