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 ,进行停止。

具体实现

在这里需要转到 AbstractApplicationrefresh 方法。

// 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 方法做了什么相关推荐

  1. Spring中ApplicationContext的getBean()方法

    getBean一共有以下四种方法原型: (1)getBean(String name) :通过id或name去查找获取bean. 参数name表示IOC容器中已经实例化的bean的id或者name,且 ...

  2. Spring中ApplicationContext加载机制和配置初始化

    转自:http://liuwei1578.blog.163.com/blog/static/495803642007116111923195/ Spring中ApplicationContext加载机 ...

  3. Spring中ApplicationContext的事件机制

    ApplicationContext事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件 ...

  4. Spring中ApplicationContext加载机制

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp33 加载器目前有两种选择:ContextLoaderListener和Co ...

  5. Spring中获取request的方法及其线程安全性分析

    在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对象,比如获取客户端ip地址.请求的url.header中的属性(如cookie.授权信息).body中的数据等.由于 ...

  6. Spring中策略模式实现方法

    一.定义 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式.在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而 ...

  7. Spring中ApplicationContext和beanfactory区别

    BeanFacotry是spring中比较原始的Factory.如XMLBeanFactory就是一种典型的BeanFactory.原始的BeanFactory无法支持spring的许多插件,如AOP ...

  8. java spring scope_如何在Spring中自定义scope的方法示例

    大家对于 Spring 的 scope 应该都不会默认.所谓 scope,字面理解就是"作用域"."范围",如果一个 bean 的 scope 配置为 sing ...

  9. Java和Spring中线程池创建方法

    一.线程池定义 1.JDK中线程池类图 Executor:父接口,所有线程池都实现了这个接口,里面有一个excute()方法用于执行线程 ExecutorService:线程池接口,继承自Execut ...

最新文章

  1. 网站针对baidu的优化技巧
  2. @staticmethod和@classmethod的作用与区别
  3. iPhone 11“机模”上手:硕大后置相机模组很突兀
  4. win10 安装flutter记录
  5. 数据分享 | 高光谱遥感影像数据集汇总
  6. STRIX z490i 10700k Monterey12.3黑苹果EFI分享
  7. ArcGIS应用(十六)Arcgis 点对连线制作航空线路图
  8. win7 IE11下,无法通过Windows更新为其他微软产品获取更新
  9. [Algorithmic Toolbox学习笔记][week6]Placing Parentheses
  10. siggraph_Siggraph的统一性
  11. Linux下dcm2niix使用
  12. 一次由图片引起的致命崩溃问题
  13. LeetCode412_412. Fizz Buzz
  14. 使用 IBM Bluemix 容器构建 Django 环境
  15. Cocos Creator生成方形
  16. 算法系列10—基数排序
  17. 集成电路layout设计的与candence讲义
  18. 防灾科技学院GKCTF2020_misc wp
  19. Android股票K线图
  20. 电力-故障录波(向量图)

热门文章

  1. 很多条update语句mysql优化_MySQL批量update语句优化
  2. “00后”来了!数睿数据迎来新生代「无代码」生力军
  3. 后台返回视频流,前台播放和下载
  4. Java实现 LeetCode 455 分发饼干
  5. 小胖和三叔一起挖呀挖呀挖
  6. 使用arduino D1 wifi模块(WeMos D1)连接阿里云物联网平台并成功实现APP点亮板载LED(四)---阿里云物联网平台使用基础
  7. 开发中VSS、RSS、PSS、USS的区别
  8. vim配置python开发环境_Win10系统下安装编辑器之神(The God of Editor)Vim并且构建Python生态开发环境(2020年最新攻略)...
  9. cxf的web service服务,包含client端、service端
  10. 畅游无限游戏盒子(二)--推箱子