前言
Refresh方法
ConfigurableApplicationContext#refresh 中进行定义
经过对该方法的注解解读,发现该方法提供了从加载配置单例bean创建的功能。
这个方法用来加载刷新配置,这些配置可能来自, java 配置、 xml 文件、 properties 文件,关系型数据库,或者其他格式。作为一个启动方法,它应当在初始化失败后销毁已经创建了的单例,防止占着资源不用。也就是说调用这个方法,要么没有所有的单例被创建、要么没有没有单例对象创建。
由AbstractApplicationContext#refresh 实现
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//1 Prepare this context for refreshing.
prepareRefresh();
//2 Tell the subclass to refresh the internal bean factory.
// 为什么要从子类获得刷新后的BeanFactory?
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3 Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
//4 Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//5 Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//6 Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
//7 Initialize message source for this context.
initMessageSource();
//8 Initialize event multicaster for this context.
initApplicationEventMulticaster();
//9 Initialize other special beans in specific context subclasses.
onRefresh();
//10 Check for listener beans and register them.
registerListeners();
//11 Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//12 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 {
//13 Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore... resetCommonCaches();
}
}
}
![](https://img-blog.csdnimg.cn/3f58d32e038a467bb362a9e20dc06a0f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
在refresh方法中做的操作
刷新前置的准备 环境属性的添加 然后初始化一些事件监听器列表等等。
整个流程如上图,其中最关键的在于下面的6个方法。
obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
![](https://img-blog.csdnimg.cn/9a33baedb6dd4eeb981986a203cdcdb8.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_9,color_FFFFFF,t_70,g_se,x_16)
对应的实现有AbstractRefreshableApplicationContext、GenericApplicationContext两个类。
AbstractRefreshableApplicationContext
- 自定义Bean工厂属性:Bean定义重写、循环引用等配置
- 创建DefalutListableBeanFactory实例
- 设置ID
- 等待子类实现的,向bean工厂注册Bean定义
- 持有bean工厂实例,以便在getBeanFactory方法中返回出去
![](https://img-blog.csdnimg.cn/5015fb846c794b03a182c9d264d2cf37.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
GenericApplicationContext
GenericApplicationContext中的刷新方法,只能被调用一次,被Atomic的refreshed状态控制着。
![](https://img-blog.csdnimg.cn/7285a592758a4d22a4429413a2344a01.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
刷新的方法也很简单,只是设置了一个ID。
prepareBeanFacotry
- 给bean工作准备ClassLoader、SPL表达是解析器、属性编辑注册器等
- 向BeanFactory注册ApplicationContextAwareProcessor
- 依赖需要使用的bean,IOC容器自己的多角色身份 @Autowried方式获得下列类型bean
-
注入ApplicationListeners接口实现的发现处理器,同时带有销毁、bean定义混合的实现。
-
操作系统环境变量:JAVA_HOME等
![](https://img-blog.csdnimg.cn/6c48de3785944ca99594a70aede55b04.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
![](https://img-blog.csdnimg.cn/8615da19782048c1b44b1b13bfda2206.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
BeanPostProcessor的注入
![](https://img-blog.csdnimg.cn/99125f02875c4693adbe96caba6e9b85.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
![](https://img-blog.csdnimg.cn/e45328c9e0764701902e2b2f34ae417e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
invokeBeanFactoryPostProcessors
![](https://img-blog.csdnimg.cn/bc40e6cf5ab14261b7651084b9c66988.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法解读
BeanFactoryPostProcessor与容器
![](https://img-blog.csdnimg.cn/8b792d31af2345b998e9d1b72e279f92.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
BeanFactoryPostProcessors的调用处理
![](https://img-blog.csdnimg.cn/97a2053aaf8c4aadaea7d9371ec7ab9e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
registerBeanPostProcessors
![](https://img-blog.csdnimg.cn/49437f6ad02c4abc89b3701276b52896.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
PostProcessorRegistrationDelegate.registerBeanPostProcessors
initMessageSource
此时BenPostProcessor都已经注册完成,下一步准备资源国际化的事宜。
![](https://img-blog.csdnimg.cn/17598504639f43cf9040556e20585fec.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
registerListeners
国际化资源准备完毕,接下来,检查事件监听器,并注册到事件传播器上。在不生成Bean对象的情况下添加ApplicationListener bean作为监听器
![](https://img-blog.csdnimg.cn/369b3e90fb3b411eb64ff55a2989a94e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_19,color_FFFFFF,t_70,g_se,x_16)
这两种去获取 beanfactory的方式。 效果都是一样的。
finishBeanFactoryInitialization
![](https://img-blog.csdnimg.cn/bbbd95e3acfd402bbc9124e5447a36f2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
![](https://img-blog.csdnimg.cn/53073aec5769457f801ac735088adb1e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)
容器的关闭
![](https://img-blog.csdnimg.cn/452803bd55334f8eb3d55a47861d52d0.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Lip6Lip6Lip5LuO6Lip,size_20,color_FFFFFF,t_70,g_se,x_16)