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

具体实现

在这里需要转到 AbstractApplicationrefresh 方法。


	// 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版权协议,转载请附上原文出处链接和本声明。