上篇介紹了run()方法中context三連中的prepareContext()方法,先貼一下這個三連:
這篇的重點是refreshContext()方法,先看一下這個方法:
接下來的方法比較多,想着自己寫有點懶了,看到其他文章中直接在源碼中添加註釋的方法還挺直觀的 ,接下來就當一下搬運工,自己也補充了部分地方,下面的原文出處:
作者:ygxing
鏈接:https://www.jianshu.com/p/7317626794fa
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
先看refresh()方法,這個方法最終主要邏輯在AbstractApplicationContext類的refresh()方法中,直接看這個方法:
/**
* 抽象父類ApplicationContext
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//準備刷新
prepareRefresh();
//刷新beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//準備beanFactory
prepareBeanFactory(beanFactory);
try {
//beanFactory的後置處理器
postProcessBeanFactory(beanFactory);
//實現beanFactory的後置處理器
invokeBeanFactoryPostProcessors(beanFactory);
//beanFactory註冊後置處理器
registerBeanPostProcessors(beanFactory);
//初始化messageSource
initMessageSource();
//初始化Application事件發佈器
initApplicationEventMulticaster();
//初始化其他特殊的bean
onRefresh();
//註冊監聽器
registerListeners();
//完成beanFactory初始化
finishBeanFactoryInitialization(beanFactory);
//完成刷新,發佈完成事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
//打印告警日誌
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
//捕獲到異常,銷燬已經註冊的bean
destroyBeans();
//捕獲到異常,取消刷新
cancelRefresh(ex);
//拋出異常
throw ex;
}
finally {
//重置緩存
resetCommonCaches();
}
}
}
}
具體的還需要一個一個方法的看。
一.準備刷新prepareRefresh():
public class AnnotationConfigServletWebServerApplicationContext
extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {
//準備刷新
@Override
protected void prepareRefresh() {
//如果類掃描器中的metadataReaderFactoryy是CachingMetadataReaderFactory的子類
//那麼清除類掃描器中beanFactory維護的所有的bean
this.scanner.clearCache();
//顯式調用父類AbstractApplicationContext的prepareRefresh方法
super.prepareRefresh();
}
}
看一下其父類AbstractApplicationContext的prepareRefresh:
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
//準備刷新
protected void prepareRefresh() {
//記錄開始時間,調整active狀態
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
//打印debug日誌
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
//初始化佔位符,例如:$,#,{}
//GenericWebApplicationContext#initPropertySources
initPropertySources();
//當前environment爲StandardServletEnvironment
//調用AbstractEnvironment#validateRequiredProperties()方法
//然後調用AbstractPropertyResolver#validateRequiredProperties()方法
//如果屬性中缺少requiredProperties
//那麼拋出MissingRequiredPropertiesException
getEnvironment().validateRequiredProperties();
if (this.earlyApplicationListeners == null) {
//如果earlyApplicationListeners爲null
//保存applicationListeners
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
//如果earlyApplicationListeners不爲null
//將earlyApplicationListeners同步到applicationListeners中
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
//初始化earlyApplicationEvents
this.earlyApplicationEvents = new LinkedHashSet<>();
}
}
二.獲取並刷新obtainFreshBeanFactory();
public abstract class AbstractApplicationContext extends DefaultResourceLoader{
//id獲取
private String id = ObjectUtils.identityToString(this);
//刷新並返回beanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
@Override
public String getId() {
return this.id;
}
}
AbstractApplicationContext中定義了模板方法, refreshBeanFactory和getBeanFactory調用的是GenericApplicationContext中實現的方法:
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
//內部的beanFactory
private final DefaultListableBeanFactory beanFactory;
//原子bool值
private final AtomicBoolean refreshed = new AtomicBoolean();
//刷新beanFactory
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
//原子自旋, 更新refreshed爲true
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
//調用AbstractApplicationContext的getId()方法
this.beanFactory.setSerializationId(getId());
}
//返回beanFactory
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
}
更新this.refreshed字段爲true, 表示已經更新了, 然後beanFactory設置serializationId, 最後返回beanFactory。
三.prepareBeanFactory(beanFactory)準備beanFactory
public abstract class AbstractApplicationContext extends DefaultResourceLoader{
protected void prepareBeanFactory()(ConfigurableListableBeanFactory beanFactory) {
//beanFactory設置爲當前context的classLoader
beanFactory.setBeanClassLoader(getClassLoader());
//beanFactory設置BeanExpressionResolver,解析EL表達式
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//beanFactory配置屬性編輯器,也就是類型轉換器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//ApplicationContextAwareProcessor會在加載Aware接口的時候, 傳遞參數到相應的Aware實現類中
//所以需要忽略Aware接口的自動裝配
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);
// 配置自動裝配規則, 例如@Autowired註解注入
// 如果需要BeanFactory,那麼注入beanFactory
// 如果需要ResourceLoader,ApplicationEventPublisher,ApplicationContext,則注入this
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//添加ApplicationListenerDetector的beanPostProcessor
//ApplicationListenerDetector會檢測實現了ApplicationListener接口的bean
//在這些bean在實例化的過程中,記錄到singletonNames 中
//在bean被銷燬的時候, 從applicationContext的applicationEventMulticaster中移除
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//添加LoadTimeWeaverAwareProcessor
//解析@EnableLoadTimeWeaving註解
//在類加載到JVM中時, 織入切面
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
//添加bean處理器,實現對AspectJ的支持
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
//設置classloader
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 手工註冊environment的相關bean
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是GenericApplicationContext中DefaultListableBeanFactory類型的成員變量, 設置beanFactory, 一共執行了
- 配置classLoader爲當前context的classLoader
- 設置BeanExpressionResolver, 解析EL表達式
- 設置屬性編輯器
- 添加BeanPostProcessor
- 配置自動裝配
- 手工註冊environment相關bean
四.beanFactory的後置處理器 postProcessBeanFactory(beanFactory)
public class AnnotationConfigServletWebServerApplicationContext
extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {
//處理beanFactory
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//顯式調用父類ServletWebServerApplicationContext#postProcessBeanFactory
super.postProcessBeanFactory(beanFactory);
//basePackages默認爲null
if (this.basePackages != null && this.basePackages.length > 0) {
//不爲空的話,進行掃描
this.scanner.scan(this.basePackages);
}
//annotatedClasses默認爲空
if (!this.annotatedClasses.isEmpty()) {
//不爲空的話註冊類
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
}
後續處理各個beanFactory, 當前applicationContext是AnnotationConfigServletWebServerApplicationContext的實例, postProcessBeanFactory執行了三步
- 調用了父類方法
- 判斷basePackages是否爲空, 不爲空的話, 掃描this.basePackages
- 判斷annotatedClasses是否爲空, 不爲空的話, 註冊bean
其父類的postProcessBeanFactory()方法:
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
implements ConfigurableWebServerApplicationContext {
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//在ServletContext和ServletConfig初始化之前
//進行bean處理
beanFactory.addBeanPostProcessor(
new WebApplicationContextServletContextAwareProcessor(this));
//忽略ServletContextAware自動配置
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
//beanFactory註冊web應用scopes
//request和session
registerWebApplicationScopes();
}
}
進行了兩個操作, 首先添加了一個WebApplicationContextServletContextAwareProcessor的Aware Bean處理器, ServletContextAware的子類Bean在實例化過程中, 會被注入servletContext和servletConfig對象, 然後beanFactory中註冊了request和session兩個scopes, 註冊了幾個Autowired依賴類。看一下這個registerWebApplicationScopes()方法:
這裏的ExistingWebApplicationScopes簡單介紹一下,第二篇(https://blog.csdn.net/weixin_42447959/article/details/104943589)中有提到@scope註解,它的value可以設置爲以下幾種:
單例(singleton):在整個應用中,只創建bean的一個實例。
原型(prototype):每次注入或者通過Spring應用上下文獲取的時候,都會創建一個新的實例。
會話(session):在Web應用中,爲每個會話創建一個bean實例。
請求(request):在Web應用中,爲每個請求創建一個bean實例。
這裏注意session和request都是在Web應用中才有的,這個ExistingWebApplicationScopes就是註冊了這兩種scope類型,具體就不點進去看了,感興趣的可以看一下。重點還是WebApplicationContextUtils的registerWebApplicationScopes()方法:
public abstract class WebApplicationContextUtils# {
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
//傳入ServletContext爲null
registerWebApplicationScopes(beanFactory, null);
}
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
@Nullable ServletContext sc) {
//註冊Scope
//request
beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
//session
beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
if (sc != null) {
//傳入sc爲null
//註冊application scope
ServletContextScope appScope = new ServletContextScope(sc);
beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
// 設置ServletContext屬性
sc.setAttribute(ServletContextScope.class.getName(), appScope);
}
//註冊幾個Autowired自動裝配
//ServletRequest.class
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
//ServletResponse.class
beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
//HttpSession.class
beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
//WebRequest.class
beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
if (jsfPresent) {
//jsfPresent默認爲false
FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
}
}
}
上面說到註冊了session和request這兩種scope類型,這裏面又註冊ServletRequest, ServletResponse, HttpSession,和WebRequest這四個。
五.invokeBeanFactoryPostProcessors(beanFactory)實例化並調用beanFactory所有已註冊的後置處理器
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//處理器代理類
//處理this.beanFactoryPostProcessors中維護的bean處理器
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
//TempClassLoader爲空
//包含了LoadTimeWeaver(加載到JVM時, 進行切面織入)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
BeanFactoryPostProcessor是一個接口, 處理beanFactory中所有的bean, 在所有的beanDefinition加載完成之後, BeanFactoryPostProcessor可以對beanDefinition進行屬性的修改, 之後再進行bean實例化
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口, 定義了postProcessBeanDefinitionRegistry方法, 會在postProcessBeanFactory方法執行之前, 獲取bean定義, 並註冊到spring容器中。
看一下PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors()方法:
final class PostProcessorRegistrationDelegate {
/**
* @param beanFactory
* @param beanFactoryPostProcessors有三個:
* CachingMetadataReaderFactoryPostProcessor
* ConfigurationWarningsPostProcessor
* PropertySourceOrderingPostProcessor
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//processedBeans記錄處理過的bean名稱
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
//優先處理傳入的BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//非BeanDefinitionRegistryPostProcessor類型, 常規BeanFactory後置處理器
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//BeanDefinitionRegistryPostProcessor類型的bean定義註冊器後置處理器
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//regularPostProcessors有1個:PropertySourceOrderingPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//bean定義註冊器後置處理器,有如下兩個:
//CachingMetadataReaderFactoryPostProcessor
//ConfigurationWarningsPostProcessor
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//執行其postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//然後加入到registryProcessors中
registryProcessors.add(registryProcessor);
}
else {
//如果不是BeanDefinitionRegistryPostProcessor
//那麼放入regularPostProcessors(常規後置處理器)中
regularPostProcessors.add(postProcessor);
}
}
//處理beanFactory中註冊的BeanDefinitionRegistryPostProcessor
//當前正在處理的PostProcessor, 處理完成之後會清空
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//將其名稱放入postProcessorNames數組中
//當前只能獲取到一個bean:
//名稱爲org.springframework.context.annotation.internalConfigurationAnnotationProcessor
//類型爲ConfigurationClassPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//優先處理PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//處理完成之後, 放到processedBeans列表
processedBeans列表中.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
//添加到registryProcessors
registryProcessors.addAll(currentRegistryProcessors);
//遍歷currentRegistryProcessors,調用其postProcessBeanDefinitionRegistry方法
//執行ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry, 掃描並註冊模塊中@Configuration註解的bean
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空currentRegistryProcessors
currentRegistryProcessors.clear();
// 實現Order註解的bean
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 最後,調用其他的BeanDefinitionRegistryPostProcessor的方法
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//調用其他BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//調用BeanDefinitionRegistryPostProcessor的postProcessBeanFactory
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//方法傳入普通BeanFactoryPostProcessor, 實現其postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
//如果beanFactory不是BeanDefinitionRegistry
//方法傳入普通BeanFactoryPostProcessor, 實現其postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//處理beanFactory中註冊的普通BeanFactoryPostProcessor
//非BeanDefinitionRegistryPostProcessor類型後置處理器
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
//說明已經處理過了
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//優先處理實現了PriorityOrdered接口的子類
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
//再處理實現了Ordered接口的子類
orderedPostProcessorNames.add(ppName);
}
else {
//最後處理其他BeanFactoryPostProcessor
nonOrderedPostProcessorNames.add(ppName);
}
}
//實現了PriorityOrdered接口的BeanFactoryPostProcessor, 優先處理
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 實現了Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 最後再實現不排序BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清除緩存
beanFactory.clearMetadataCache();
}
}
如果beanFactory是BeanDefinitionRegistry的子類, 按優先級處理BeanDefinitionRegistryPostProcessor類型的後置處理器, 最後處理傳入的其他類型後置處理器, 處理流程如下:
首先處理傳入的beanFactoryPostProcessors, 將傳入的beanFactoryPostProcessors分爲兩個部分
- BeanDefinitionRegistryPostProcessor子類, 執行其postProcessBeanDefinitionRegistry方法, 然後維護到registryProcessors的列表中
- 非BeanDefinitionRegistryPostProcessor子類, 維護到regularPostProcessors列表中
然後處理beanFactory中註冊的BeanDefinitionRegistryPostProcessor類型的bean
1.優先處理實現了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor, 一共分爲5個步驟
- 生成bean, 維護到currentRegistryProcessors列表中
- processedBeans中添加bean名稱, 標記已經被處理
- currentRegistryProcessors列表排序, 並添加到registryProcessors中
- 遍歷registryProcessors列表, 調用每個元素的postProcessBeanDefinitionRegistry方法
- 然後清空currentRegistryProcessors
2.然後處理實現了Ordered接口的BeanDefinitionRegistryPostProcessor, 一共分爲5個步驟
- 先判斷processedBeans中是否包含了beanName, 如果包含了就不處理
- 生成bean, 維護到currentRegistryProcessors列表中
- processedBeans中添加bean名稱, 標記已經被處理
- currentRegistryProcessors列表排序, 並添加到registryProcessors中
- 遍歷registryProcessors列表, 調用每個元素的postProcessBeanDefinitionRegistry方法
- 然後清空currentRegistryProcessors
3.處理剩下的所有BeanDefinitionRegistryPostProcessor, 方法同第2步
4.遍歷registryProcessors, 調用其postProcessBeanFactory方法
5.遍歷所有的regularPostProcessors, 調用其postProcessBeanFactory方法
如果beanFactory不是BeanDefinitionRegistry的子類, 那麼直接遍歷傳入的傳入的beanFactoryPostProcessors, 調用元素的postProcessBeanFactory方法
最後處理beanFactory中註冊的其他類型的BeanFactoryPostProcessor, 獲取bean名稱, 維護到postProcessorNames列表中, 之後的處理步驟如下:
- 首先處理實現了PriorityOrdered接口的BeanFactoryPostProcessor
- 獲取bean, 維護到priorityOrderedPostProcessors列表中
- priorityOrderedPostProcessors排序
- 遍歷priorityOrderedPostProcessors, 執行其postProcessBeanFactory方法
2.然後處理實現了Ordered接口的BeanFactoryPostProcessor, 方法同上
3.最後處理其他BeanFactoryPostProcessor, 方法同上
ConfigurationClassPostProcessor處理了@Configuration註解, 掃描項目中的BeanDefinition。
六.註冊bean處理器 registerBeanPostProcessors(beanFactory)
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
//註冊beanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
}
BeanPostProcessor是一個接口, Bean後置處理器, 在bean實例化, 之前執行postProcessBeforeInitialization方法, 在bean實例化之後執行postProcessAfterInitialization方法, 實現了對bean實例的增強。
看一下這個registerBeanPostProcessors()方法:
final class PostProcessorRegistrationDelegate {
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 添加一個BeanPostProcessorChecker
// beanFactory數量不符合時,會打印info日誌
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// BeanPostProcess分類
// 實現了PriorityOrdered接口
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//實現了MergedBeanDefinitionPostProcessor接口
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 實現了Ordered接口
List<String> orderedPostProcessorNames = new ArrayList<>();
// 沒有實現排序接口
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//PriorityOrdered子類
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//MergedBeanDefinitionPostProcessor子類
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// Ordered子類
orderedPostProcessorNames.add(ppName);
}
else {
// 普通BeanPostProcessor
nonOrderedPostProcessorNames.add(ppName);
}
}
// 實現了PriorityOrdered接口的BeanPostProcessor, 先排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 然後添加到beanFactory中
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 實現了Ordered接口的BeanPostProcessor
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
// 先從beanFactory中獲取bean
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
// 然後添加到orderedPostProcessors列表中
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
// 如果是MergedBeanDefinitionPostProcessor的子類
// 那麼加入internalPostProcessors中
internalPostProcessors.add(pp);
}
}
// 排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 添加到beanFactory中
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 添加其他BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
// 如果是MergedBeanDefinitionPostProcessor的子類
// 那麼加入internalPostProcessors中
internalPostProcessors.add(pp);
}
}
// 添加到beanFactory中
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最後internalPostProcessors排序
// 添加到beanFactory中
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 添加一個ApplicationListenerDetector的beanFactory
// 處理ApplicationListener類型的bean
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
}
beanFactory中獲取BeanPostProcessor類型的bean名稱, 維護到postProcessorNames數組中, 將BeanPostProcessor列表分爲四類:
- 實現了PriorityOrdered接口, 維護到priorityOrderedPostProcessors列表中
- 實現了Ordered接口的BeanPostProcessor, 維護到orderedPostProcessorNames列表中
- 沒有實現排序接口的, 維護到nonOrderedPostProcessorNames列表中
- 實現了MergedBeanDefinitionPostProcessor接口, 維護到internalPostProcessors列表中
beanFactory先添加一個BeanPostProcessorChecker類型的BeanPostProcessor, 然後在將各類PostProcessors列表排序, 分別添加到beanFactory的beanPostProcessor列表中, 最後再添加一個ApplicationListenerDetector。
七.國際化 initMessageSource()
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//判斷容器中是否包含messageSource bean定義
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
//容器中存在bean定義, 那麼直接獲取bean
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
//HierarchicalMessageSource可以實現消息的嵌套
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
//容器中沒有messageSource bean定義
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
//手工註冊一個單例messageSource bean
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
先判斷容器beanFactory中是否包含messageSource bean定義, 存在的話, 直接獲取bean, 如果不存在的話, 那麼手工註冊一個messageSource單例bean, 然後賦值給this.messageSource。
八.註冊事件發佈器 initApplicationEventMulticaster()
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//先判斷容器beanFactory中是否有applicationEventMulticaster bean定義
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
//存在的話, 獲取bean實例
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
//容器中不存在的話, 實例化一個SimpleApplicationEventMulticaster
//手工註冊一個單例bean
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
先判斷容器beanFactory中是否有applicationEventMulticaster bean定義, 存在的話, 獲取bean實例, 不存在的話, 實例化一個SimpleApplicationEventMulticaster, 手工註冊一個單例bean, 然後賦值給this.applicationEventMulticaster。
九.通知子類刷新刷新容器 onRefresh()
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
implements ConfigurableWebServerApplicationContext {
@Override
protected void onRefresh() {
//調用父類onRefresh方法
super.onRefresh();
try {
//創建webServer
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
//創建webServer
private void createWebServer() {
WebServer webServer = this.webServer;
//默認servletContext爲null
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
//獲取一個ServletWebServerFactory
ServletWebServerFactory factory = getWebServerFactory();
//factory獲取一個webServer
this.webServer = factory.getWebServer(getSelfInitializer());
}
else if (servletContext != null) {
try {
//servletContext不爲空
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context",
ex);
}
}
//初始化
initPropertySources();
}
}
AbstractApplicationContext沒有實現該方法, 用於通知子類刷新容器。
調用父類GenericWebApplicationContext#onRefresh方法, 然後創建webServer, 之後調用父類GenericWebApplicationContext#initPropertySources方法, 將servletContext維護到environment的servletContextInitParams屬性中。
其父類的onRefresh():
public class GenericWebApplicationContext extends GenericApplicationContext
implements ConfigurableWebApplicationContext, ThemeSource {
@Override
protected void onRefresh() {
//初始化資源
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}
}
初始化主題, 可以讓頁面顯示不同的樣式。
十.註冊監聽器 registerListeners()
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void registerListeners() {
// 首先將硬編碼的ApplicationListener先添加applicationEventMulticaster中
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 然後將注入的listener bean維護到applicationEventMulticaster中
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 處理earlyEvent
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
}
首先將硬編碼的ApplicationListener先添加this.applicationEventMulticaster.defaultRetriever.applicationListeners中, 然後將注入的listener bean維護到this.applicationEventMulticaster.defaultRetriever.applicationListenerBeans, 最後處理earlyEvent。
十一.完成beanFactory初始化, 實例化所有非延遲加載的bean
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化ConversionService的實例化
// 然後賦值給beanFactory.conversionService實例
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 如果beanFactory中沒有@Value解析器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 類加載期間織入的切面
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
//實例化所有LoadTimeWeaverAware類型的bean
getBean(weaverAwareName);
}
//停止使用臨時ClassLoader
beanFactory.setTempClassLoader(null);
//凍結配置,不再允許改變
beanFactory.freezeConfiguration();
//實例化所有非延遲加載的bean
beanFactory.preInstantiateSingletons();
}
}
十二.完成刷新 finishRefresh()
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void finishRefresh() {
// 清空緩存
clearResourceCaches();
// 初始化一個LifecycleProcessor
// 在Spring啓動的時候啓動bean
// 在spring結束的時候銷燬bean
initLifecycleProcessor();
// 調用LifecycleProcessor的onRefresh方法
// 啓動實現了Lifecycle接口的bean
getLifecycleProcessor().onRefresh();
// 發佈ContextRefreshedEvent
publishEvent(new ContextRefreshedEvent(this));
// 如果配置了"spring.liveBeansView.mbeanDomain"的系統屬性,制定了MBeanServer,
// 那麼會將ApplicationContext註冊到MBeanServer中,
// 可以通過MBeanServer,對spring容器中的bean,進行實時的查看和管理
LiveBeansView.registerApplicationContext(this);
}
}
十三.異常處理
//beanFactory銷燬註冊的bean
destroyBeans();
//ApplicationContext取消刷新
cancelRefresh(ex);
十四.清除緩存 resetCommonCaches()
protected void resetCommonCaches() {
//反射工具類的緩存清空
ReflectionUtils.clearCache();
//註解工具類的緩存清空
AnnotationUtils.clearCache();
//ResolvableType的緩存清空
ResolvableType.clearCache();
//清空ClassLoader
CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
最後總結一下,這個過程主要分析了spring容器的刷新, 首先更新刷新狀態, 然後處理beanFactory的後置處理器, 用於註冊bean定義, 其中ConfigurationClassPostProcessor處理器, 處理模塊中@Configuration註解, onRefresh()方法中, 實例化了TomcatWebServer, 最後在finishRefresh()中, 實例化了所有bean。
嚯,一下子搬了這麼多,到這裏context三連的第二連refreshContext()其實還沒寫完,搬了有點多再貼一遍這個方法:
這才分析了refresh()方法,其實下面的shutdownHook也值得專門一篇文章,下篇不搬了好好總結,這篇就不總結了,直接接下篇。