refresh 方法可以说是Spring中核心的一个方法了,通过这个方法可以获取bean的定义、创建添加bean到spring容器中一个其它扩展功能。记录下相关内容。
有个问题:refresh方法为什么要叫 refresh,其实从下文中就可以看出来为什么要叫refresh。
方法文档说明
加载或刷新配置的持久化表示形式,这个配置可以是java 代码的配置,也可以是xml文件、properties文件一个关系型数据库样式或者其它文件格式。
由于这是一种启动方法,因此,如果失败,则应销毁已创建的单例,以避免悬挂资源。 换句话说,在调用此方法之后,应实例化所有单例或根本不实例化。
这里就是对这个方法实现进行规定,可以通过注解方式
@Bean、@Service等方式,也可以通过xml的配置<bean >这些。如果在refresh 异常了,就要销毁所有的已创建的bean。
实现关系
springboot框架下,添加了mvc 和 react 两个依赖,可以看出有三个实现。
下面两个类都是AbstractApplicationContext的子类,这里先不关注 AbstractApplicationContext 的实现。看其它两个方法的内容。
ServletWebServerApplicationContext

ReactiveWebServerApplicationContext
这个发现两个实现类都是先调用完成父类的refresh方法后,再实现自己的逻辑功能。如已经有了启动的 tomcat等WebServer ,进行停止。
具体实现
在这里需要转到 AbstractApplication 的 refresh 方法。
// AbstractApplicationContext
@Override
public void refresh() throws BeansException, IllegalStateException {
// 加锁
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 准备刷新
// 设置启动日期和一些启动标识
prepareRefresh();
// 获取 BeanFactory
// 这个是比较重要的一个方法,总共分两步:1、刷新BeanFactory 2、获取BeanFactory
// 其中重要的又是刷新 BeanFactory,这一步又可以分为两步:
// 1、如果已经有BeanFactory,进行销毁其中所有的bean,最后销毁这个 BeanFacory。这也解释了为什么叫 refresh
// 2、创建一个 DefaultListableBeanFactory 的BeanFactory 实例,并把配置的bean 封装成 BeanDefinition,
// 根据bean 名称和 BeanDefinition 添加到这个 BeanFactory 中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 添加了一些 BeanPostProcessor 实例,用于每一个后续 bean 创建
prepareBeanFactory(beanFactory);
try {
// 模板方法:允许添加一些 BeanFactoryPostProcessor ,用户定义 BeanFactory
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 执行 BeanFactoryPostProcessor 的对BeanFactory实现逻辑
// 从两个地方获取。1、手动添加的 2、BeanDedinition 中获取到的实现了 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 添加所有的 BeanPostProcessor 的 bean 到一个集合中,用于每一个bean 创建的自定义处理
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 模板方法:这个这个模板类中也没有实现,供子类扩展。
// 如 ServletWebServerApplicationContext 中有一个创建 Web
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();
contextRefresh.end();
}
}
}
版权声明:本文为weixin_42245133原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。