Spring5源碼解析3-refresh方法初探

接上回分析完register(annotatedClasses);後,如今來看一下refresh();方法。java

// new AnnotationConfigApplicationContext(AppConfig.class); 源碼
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
	//調用默認無參構造器,裏面有一大堆初始化邏輯
	this();

	//把傳入的Class進行註冊,Class既能夠有@Configuration註解,也能夠沒有@Configuration註解
	//怎麼註冊? 委託給了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法進行註冊
	// 傳入Class 生成 BeanDefinition , 而後經過 註冊到 BeanDefinitionRegistry
	register(annotatedClasses);

	//刷新容器上下文
	refresh();
}
複製代碼

refresh方法

點開refresh();方法,裏面調用了超級多的方法,咱們一個個來看。git

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
    	// Prepare this context for refreshing.
    	//準備上下文,設置其啓動日期和活動標誌,執行屬性源的初始化
    	prepareRefresh();
    
    	// Tell the subclass to refresh the internal bean factory.
    	//調用子類 refreshBeanFactory()方法
    	//獲取 BeanFactory 實例 DefaultListableBeanFactory , DefaultListableBeanFactory 實現了 ConfigurableListableBeanFactory 接口
    	ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
    	// Prepare the bean factory for use in this context.
    	//配置 beanFactory 上下文
    	//1.添加 ApplicationContextAwareProcessor 和 ApplicationListenerDetector
    	//2.忽略部分類型的自動裝配
    	//3.註冊特殊的依賴類型,並使用相應的autowired值
    	//4.註冊默認的environment beans
    	//5.設置environment beans
    	prepareBeanFactory(beanFactory);
    
    	try {
    		// Allows post-processing of the bean factory in context subclasses.
    		//留給子類去擴展的一個方法
    		postProcessBeanFactory(beanFactory);
    
    		// Invoke factory processors registered as beans in the context.
    		invokeBeanFactoryPostProcessors(beanFactory);
    
    		// Register bean processors that intercept bean creation.
    		registerBeanPostProcessors(beanFactory);
    
    		// Initialize message source for this context.
    		initMessageSource();
    
    		// Initialize event multicaster for this context.
    		initApplicationEventMulticaster();
    
    		// Initialize other special beans in specific context subclasses.
    		onRefresh();
    
    		// Check for listener beans and register them.
    		registerListeners();
    
    		// Instantiate all remaining (non-lazy-init) singletons.
    		finishBeanFactoryInitialization(beanFactory);
    
    		// Last step: publish corresponding event.
    		finishRefresh();
    	} catch (BeansException ex) {
    		if (logger.isWarnEnabled()) {
    			logger.warn("Exception encountered during context initialization - " +
    					"cancelling refresh attempt: " + ex);
    		}
    
    		// Destroy already created singletons to avoid dangling resources.
    		destroyBeans();
    
    		// Reset 'active' flag.
    		cancelRefresh(ex);
    
    		// Propagate exception to caller.
    		throw ex;
    	} finally {
    		// Reset common introspection caches in Spring's core, since we
    		// might not ever need metadata for singleton beans anymore...
    		resetCommonCaches();
    	}
    }
}
複製代碼

prepareRefresh();

prepareRefresh();作的事情比較簡單:準備上下文,設置其啓動日期和活動標誌,執行屬性源的初始化。github

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.
	//這是一個空方法,AnnotationConfigApplicationContext 並無 Override 改方法
	initPropertySources();

	// Validate that all properties marked as required are resolvable:
	// see ConfigurablePropertyResolver#setRequiredProperties
	getEnvironment().validateRequiredProperties();

	// Store pre-refresh ApplicationListeners...
	if (this.earlyApplicationListeners == null) {
		//默認狀況下,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();

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	refreshBeanFactory();
	return getBeanFactory();
}
複製代碼

refreshBeanFactory(); 是一個抽象方法,它有兩個具體是實現:spring

refreshBeanFactory()

AnnotationConfigApplicationContext 繼承 GenericApplicationContext,因此很顯然此處執行的應該是GenericApplicationContext類中的方法。GenericApplicationContextrefreshBeanFactory()源碼以下:app

//GenericApplicationContext#refreshBeanFactory 源碼
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
	if (!this.refreshed.compareAndSet(false, true)) {
		throw new IllegalStateException(
				"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
	}
	this.beanFactory.setSerializationId(getId());
}
複製代碼

obtainFreshBeanFactory();方法最後調用 getBeanFactory();方法,而且返回ConfigurableListableBeanFactory對象。ide

getBeanFactory();,顧名思義就是獲取BeanFactory,Spring中使用的是 DefaultListableBeanFactory,該類也同時實現了ConfigurableListableBeanFactory接口。post

prepareBeanFactory(beanFactory);

prepareBeanFactory(beanFactory);源碼比較簡單:學習

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	// Tell the internal bean factory to use the context's class loader etc.
	beanFactory.setBeanClassLoader(getClassLoader());
	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	// Configure the bean factory with context callbacks.
	//增長 BeanPostProcessor 實例 ApplicationContextAwareProcessor
	//ApplicationContextAwareProcessor 主要做用是對 Aware接口的支持,若是實現了相應的 Aware接口,則注入對應的資源
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

	//默認狀況下,只忽略BeanFactoryAware接口,如今新增忽略以下類型的自動裝配
	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.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.
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	// Detect a LoadTimeWeaver and prepare for weaving, if found.
	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.
	//註冊默認的environment beans.
	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
		// Environment
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		// System Properties
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		// System Environment
		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
}
複製代碼

ApplicationContextAwareProcessor

prepareBeanFactory(beanFactory);方法中往beanFactory中添加了一個ApplicationContextAwareProcessor對象:beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));ui

ApplicationContextAwareProcessor類實現了BeanPostProcessor接口,其中主要是 Override 了postProcessBeforeInitialization方法,其做用主要是用來對 Aware系列接口的支持,發現Bean實現了Aware系列接口,就調用其相應的方法,具體爲哪些Aware接口,請查看源碼:this

//ApplicationContextAwareProcessor#postProcessBeforeInitialization 源碼
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
	AccessControlContext acc = null;

	if (System.getSecurityManager() != null &&
			(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
					bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
					bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
		acc = this.applicationContext.getBeanFactory().getAccessControlContext();
	}

	if (acc != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareInterfaces(bean);
			return null;
		}, acc);
	} else {
		invokeAwareInterfaces(bean);
	}

	return bean;
}

private void invokeAwareInterfaces(Object bean) {
	if (bean instanceof Aware) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}
}
複製代碼

程序運行到這裏,再看看一下Spring容器中有哪些數據:

  • 6個BeanDefinition對象
    ((DefaultListableBeanFactory) beanFactory).beanDefinitionMap
  • 3 個單例Bean
    ((DefaultListableBeanFactory) beanFactory).singletonObjects
  • 2 個BeanPostProcessor
    ((DefaultListableBeanFactory) beanFactory).beanPostProcessors

postProcessBeanFactory(beanFactory);

這是一個留給子類去拓展的空方法,AnnotationConfigApplicationContext類中的該方法沒有作任何事情。

postProcessBeanFactory(beanFactory)


未完待續......

源碼學習筆記:github.com/shenjianeng…

歡迎各位關注公衆號,你們一塊兒學習成長。

Coder小黑
相關文章
相關標籤/搜索