Spring源码-refresh方法总览

一、refresh方法总览

    @Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		/**
		 * 前戏,做容器刷新前的准备工作
		 * 1、设置容器的启动时间
		 * 2、设置活跃状态为true
		 * 3、设置关闭状态为false
		 * 4、获取Environment对象,并加载当前系统的属性值到Environment对象中
		 * 5、准备监听器和事件的集合对象,默认为空的集合
		 */

		prepareRefresh();

		
		// 创建容器对象:DefaultListableBeanFactory
		// 加载xml配置文件的属性值到当前工厂中,最重要的就是BeanDefinition
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		
		// beanFactory的准备工作,对各种属性进行填充
		prepareBeanFactory(beanFactory);

		try {
			
			// 子类覆盖方法做额外的处理,此处我们自己一般不做任何扩展工作,但是可以查看web中的代码,是有具体实现的
			postProcessBeanFactory(beanFactory);

			
			// 调用各种beanFactory处理器
			invokeBeanFactoryPostProcessors(beanFactory);

			
			// 注册bean处理器,这里只是注册功能,真正调用的是getBean方法
			registerBeanPostProcessors(beanFactory);

			
			// 为上下文初始化message源,即不同语言的消息体,国际化处理,在springmvc的时候通过国际化的代码重点讲
			initMessageSource();

			
			// 初始化事件监听多路广播器
			initApplicationEventMulticaster();

			
			// 留给子类来初始化其他的bean
			onRefresh();

			
			// 在所有注册的bean中查找listener bean,注册到消息广播器中
			registerListeners();

			
			// 初始化剩下的单实例(非懒加载的)
			finishBeanFactoryInitialization(beanFactory);

			
			// 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
			finishRefresh();
		}

		catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}

			
			// 为防止bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean
			destroyBeans();

			
			// 重置active标志
			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();
		}
	}
}

二、prepareRefresh

    	protected void prepareRefresh() {
	// 设置容器启动的时间
	this.startupDate = System.currentTimeMillis();
	// 容器的关闭标志位
	this.closed.set(false);
	// 容器的激活标志位
	this.active.set(true);

	// 记录日志
	if (logger.isDebugEnabled()) {
		if (logger.isTraceEnabled()) {
			logger.trace("Refreshing " + this);
		}
		else {
			logger.debug("Refreshing " + getDisplayName());
		}
	}


	// 留给子类覆盖,初始化属性资源
	initPropertySources();

	// 创建并获取环境对象,验证setRequiredProperties设置的属性是否都已经放入环境中
	getEnvironment().validateRequiredProperties();

	// 判断刷新前的应用程序监听器集合是否为空,如果为空,则将监听器添加到此集合中
	if (this.earlyApplicationListeners == null) {
		this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
	}
	else {
		// 如果不等于空,则清空集合元素对象
		this.applicationListeners.clear();
		this.applicationListeners.addAll(this.earlyApplicationListeners);
	}

	// 创建刷新前的监听事件集合
	this.earlyApplicationEvents = new LinkedHashSet<>();
}

三、initPropertySources扩展和setRequiredProperties实践

    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class MyClassPathApplicationContext extends ClassPathXmlApplicationContext {

public MyClassPathApplicationContext(String configLocation){
	super(configLocation);
}

@Override
protected void initPropertySources() {
	super.initPropertySources();
	getEnvironment().setRequiredProperties("a");
}
    }

结果:

添加jvm参数-Da=123后

posted @ 2022-08-27 16:12  shigp1  阅读(34)  评论(0编辑  收藏  举报