ApplicationContext.0 总体流程和prepareRefresh

115 阅读2分钟

1. 总体流程

  1. 创建设置EnvironmentResourceLoader(加载spring配置文件需要)
  2. 设置 spring 配置文件路径
  3. 处理 Environment 相关内容,包括调用和Environment有关的回调接口,判断required的环境变量
  4. 创建beanFactory设置一些配置项,配置QualifierAnnotationAutowireCandidateResolver(不知道为什么不用InstantiationAwareBeanPostProcessor),加载BeanDefinition.
  5. 配置一些applicationContex特有的属性,包括context's ClassLoader and post-processors.
  6. 调用扩展回调接口postProcessBeanFactory,容许子类对BeanFactory做一些定制化配置
  7. 查找所有的BeanFactoryPostProcessor并调用
  8. 查找并注册所有的BeanPostProcessor.
  9. 查找名称为messageSource,类型为MessageSource的bean,没有就创建,赋值给applicationContextmessageSource 成员变量
  10. 查找名称为applicationEventMulticaster,类型为ApplicationEventMulticaster的bean,没有就创建,赋值给applicationContextapplicationEventMulticaster 成员变量
  11. 调用扩展接口onRefresh。实际上springboot大部分都是通过监听器来实现扩展的,而不是子类扩展接口
  12. 将手动配置的listener和配置资源里面的listener都加入ApplicationEventMulticaster
  13. 实例化所有单例非延迟创建的bean
  14. 初始化生命周期管理器(LifecycleProcessor),调用所有实现Lifecyclebeanstart方法,并发布ContextRefreshedEvent

2. 代码解析

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
		throws BeansException {
	//主要就是执行内部Environment和ResourcePatternResolver(就是resourceLoader)的创建和设置。以及设置上级
	super(parent);
	//设置配置资源路径
	setConfigLocations(configLocations);
	if (refresh) {
		//主要处理逻辑
		refresh();
	}
}


public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			//获取messageSource类型的bean赋值给applicationContext的messageSource
			initMessageSource();

			// Initialize event multicaster for this context.
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			//子类实现
			onRefresh();

			// Check for listener beans and register them.
			//将applicationListeners里面的监听器全部放入ApplicationEventMulticaster
			//以及资源文件配置的applicationListeners
			registerListeners();

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

			// Last step: publish corresponding event.
			//调用lifecycle实例的start方法
			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;
		}
	}
}

1. prepareRefresh

protected void prepareRefresh() {
	this.startupDate = System.currentTimeMillis();

	synchronized (this.activeMonitor) {
		this.active = true;
	}

	if (logger.isInfoEnabled()) {
		logger.info("Refreshing " + this);
	}

	// Initialize any placeholder property sources in the context environment
	//参考StaticWebApplicationContext的initPropertySources(方法)
	//springboot应该是继承覆盖了该方法来实现外部配置中心的配置项加载  
	initPropertySources();

	// Validate that all properties marked as required are resolvable
	// see ConfigurablePropertyResolver#setRequiredProperties
	//applicationContext本身继承Environment接口,可以直接调用setRequiredProperties()
	getEnvironment().validateRequiredProperties();
}

2. 两个回调接口

  1. beanFactory创建加载配置完成后的回调接口postProcessBeanFactory(beanFactory);
  2. onfresh方法。