接上回分析完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();
方法,裏面調用了超級多的方法,咱們一個個來看。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();
作的事情比較簡單:準備上下文,設置其啓動日期和活動標誌,執行屬性源的初始化。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<>();
}
複製代碼
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
複製代碼
refreshBeanFactory();
是一個抽象方法,它有兩個具體是實現:spring
AnnotationConfigApplicationContext
繼承 GenericApplicationContext
,因此很顯然此處執行的應該是GenericApplicationContext
類中的方法。GenericApplicationContext
的refreshBeanFactory()
源碼以下: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);
源碼比較簡單:學習
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());
}
}
複製代碼
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容器中有哪些數據:
BeanDefinition
對象
Bean
BeanPostProcessor
這是一個留給子類去拓展的空方法,AnnotationConfigApplicationContext
類中的該方法沒有作任何事情。
未完待續......
源碼學習筆記:github.com/shenjianeng…
歡迎各位關注公衆號,你們一塊兒學習成長。