Spring容器的refresh()方法

refresh()方法是Spring容器启动的核心方法,主要有下面12个核心步骤。

1.prepareRefresh()

准备上下文刷新,重置相关状态和属性。时间戳记录、状态管理、日志输出、环境初始化事件、监听器管理、早期事件收集。

2.obtainFreshBeanFactory()

获取BeanFactory。

3.prepareBeanFactory(beanFactory)

配置BeanFactory的标准上下文特性,如类加载器、表达式解析器等属性。

4.postProcessBeanFactory(beanFactory)

允许子类对BeanFactory进行后处理操作。下面是一个子类实现。(不同子类实现不同)

5.invokeBeanFactoryPostProcessors(beanFactory)

java 复制代码
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

实例化并调用所有已注册的BeanFactoryPostProcessor ,并遵循指定的顺序(如果有的话)。此方法必须在单例Bean实例化之前被调用。

其中BeanFactoryPostProcessor有多种实现,有些需要排序,有些不需要排序,导致执行的顺序也是不一样了。

6.registerBeanPostProcessors(beanFactory)

注册bean的工厂后处理器,用于解析@Autowried已经@Resource以及@PostConstruct等需要Bean后处理器解析的注解。

7.initMessageSource()

初始化上下文的消息源,用于国际化支持。

8.initApplicationEventMulticaster()

初始化应用事件发布器。

java 复制代码
protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}
  • 检查容器中是否已定义了应用事件多播器bean
  • 如果未定义,则创建默认的SimpleApplicationEventMulticaster实例

9.onRefresh()

该方法是模板方法,具体实现在不同的ApplicationContext容器中处理不一样。

10.registerListeners()

java 复制代码
protected void registerListeners() {
		// Register statically specified listeners first.
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

注册监听器容器自带的监听器,获取容器中其它配置的监听器。发布容器的早期事件。

11.finishBeanFactoryInitialization(beanFactory)

java 复制代码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

做一些初始化的工作,如果没有其他Bean后处理器(如PropertyPlaceholderConfigurer)注册嵌入值解析器,清理临时类加载器,调用freezeConfiguration()方法缓存所有Bean定义元数据,实例化所有剩余的非懒加载单例bean,这是整个Spring容器初始化过程中的关键一步,真正创建Bean实例

12.finishRefresh()

java 复制代码
protected void finishRefresh() {
		// Clear context-level resource caches (such as ASM metadata from scanning).
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}

完成刷新过程的最后步骤,发布相应的上下文刷新完成事件。主要步骤如下:

  • 清理资源缓存;
  • 初始化生命周期处理器(LifecycleProcessor);
  • 调用生命周期处理器的 onRefresh() 方法;
  • 发布上下文刷新完成事件(ContextRefreshedEvent);
  • 注册当前上下文到 LiveBeansView MBean(若启用)。
相关推荐
悟能不能悟34 分钟前
java的java.sql.Date和java.util.Date的区别,应该怎么使用
java·开发语言
循环过三天41 分钟前
3.4、Python-集合
开发语言·笔记·python·学习·算法
高山上有一只小老虎2 小时前
java 正则表达式大全
java·正则表达式
_院长大人_2 小时前
设计模式-工厂模式
java·开发语言·设计模式
MATLAB代码顾问2 小时前
MATLAB实现决策树数值预测
开发语言·决策树·matlab
凌波粒3 小时前
MyBatis完整教程IDEA版(2)--ResultMap/注解/一对多/多对一/lombok/log4j
java·intellij-idea·mybatis
蓝-萧3 小时前
【玩转全栈】----Django基本配置和介绍
java·后端
priority_key3 小时前
排序算法:堆排序、快速排序、归并排序
java·后端·算法·排序算法·归并排序·堆排序·快速排序
不染尘.4 小时前
2025_11_7_刷题
开发语言·c++·vscode·算法
似水এ᭄往昔4 小时前
【C++】--stack和queue
开发语言·c++