spring 中 ApplicationContext 的 refresh 方法做了什么
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 @Overridepublic 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 ,用户定义 BeanFactorypostProcessBeanFactory(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 中有一个创建 WebonRefresh();// 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();}}}
spring 中 ApplicationContext 的 refresh 方法做了什么相关推荐
- Spring中ApplicationContext的getBean()方法
getBean一共有以下四种方法原型: (1)getBean(String name) :通过id或name去查找获取bean. 参数name表示IOC容器中已经实例化的bean的id或者name,且 ...
- Spring中ApplicationContext加载机制和配置初始化
转自:http://liuwei1578.blog.163.com/blog/static/495803642007116111923195/ Spring中ApplicationContext加载机 ...
- Spring中ApplicationContext的事件机制
ApplicationContext事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件 ...
- Spring中ApplicationContext加载机制
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp33 加载器目前有两种选择:ContextLoaderListener和Co ...
- Spring中获取request的方法及其线程安全性分析
在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对象,比如获取客户端ip地址.请求的url.header中的属性(如cookie.授权信息).body中的数据等.由于 ...
- Spring中策略模式实现方法
一.定义 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式.在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而 ...
- Spring中ApplicationContext和beanfactory区别
BeanFacotry是spring中比较原始的Factory.如XMLBeanFactory就是一种典型的BeanFactory.原始的BeanFactory无法支持spring的许多插件,如AOP ...
- java spring scope_如何在Spring中自定义scope的方法示例
大家对于 Spring 的 scope 应该都不会默认.所谓 scope,字面理解就是"作用域"."范围",如果一个 bean 的 scope 配置为 sing ...
- Java和Spring中线程池创建方法
一.线程池定义 1.JDK中线程池类图 Executor:父接口,所有线程池都实现了这个接口,里面有一个excute()方法用于执行线程 ExecutorService:线程池接口,继承自Execut ...
最新文章
- 网站针对baidu的优化技巧
- @staticmethod和@classmethod的作用与区别
- iPhone 11“机模”上手:硕大后置相机模组很突兀
- win10 安装flutter记录
- 数据分享 | 高光谱遥感影像数据集汇总
- STRIX z490i 10700k Monterey12.3黑苹果EFI分享
- ArcGIS应用(十六)Arcgis 点对连线制作航空线路图
- win7 IE11下,无法通过Windows更新为其他微软产品获取更新
- [Algorithmic Toolbox学习笔记][week6]Placing Parentheses
- siggraph_Siggraph的统一性
- Linux下dcm2niix使用
- 一次由图片引起的致命崩溃问题
- LeetCode412_412. Fizz Buzz
- 使用 IBM Bluemix 容器构建 Django 环境
- Cocos Creator生成方形
- 算法系列10—基数排序
- 集成电路layout设计的与candence讲义
- 防灾科技学院GKCTF2020_misc wp
- Android股票K线图
- 电力-故障录波(向量图)
热门文章
- 很多条update语句mysql优化_MySQL批量update语句优化
- “00后”来了!数睿数据迎来新生代「无代码」生力军
- 后台返回视频流,前台播放和下载
- Java实现 LeetCode 455 分发饼干
- 小胖和三叔一起挖呀挖呀挖
- 使用arduino D1 wifi模块(WeMos D1)连接阿里云物联网平台并成功实现APP点亮板载LED(四)---阿里云物联网平台使用基础
- 开发中VSS、RSS、PSS、USS的区别
- vim配置python开发环境_Win10系统下安装编辑器之神(The God of Editor)Vim并且构建Python生态开发环境(2020年最新攻略)...
- cxf的web service服务,包含client端、service端
- 畅游无限游戏盒子(二)--推箱子