【Spring】ApplicationContext 二 AbstractApplicationContext

前言

AbstractApplicationContext,抽象基类,几乎实现了顶层接口定义的所有方法,其中最核心的便是 refresh 方法,这里提供了模板方法的设计模型,将容器刷新的步骤拆解成 13 步并依次给出对应的实现,同时也允许子类去复写

版本

Spring 5.3.x

AbstractApplicationContext#refresh

	/**
	 * 核心方法:AbstractApplicationContext 定义的模板方法
	 * 加载(刷新)容器的配置,意味着整个容器的启动
	 */
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			
			prepareRefresh();
			
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			
			prepareBeanFactory(beanFactory);
			
			try {
				
				postProcessBeanFactory(beanFactory);			

				invokeBeanFactoryPostProcessors(beanFactory);
				
				registerBeanPostProcessors(beanFactory);
				
				initMessageSource();
				
				initApplicationEventMulticaster();
				
				onRefresh();
				
				registerListeners();
				
				finishBeanFactoryInitialization(beanFactory);
				
				finishRefresh();
			}
			catch (BeansException ex) {
				
				destroyBeans();
				
				cancelRefresh(ex);
				
				throw ex;
			}

			finally {
				resetCommonCaches();
			}
		}
	}

方法概览,一个个了解细节:

prepareRefresh

	protected void prepareRefresh() {
		// 设置时间戳、标识位
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		// 属性源配置,由子类实现,比如 web 环境加载 Servlet 属性等
		initPropertySources();

		// 校验所有 required 属性存在
		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<>();
	}

前置处理

  • 设置 时间戳、标识位
  • 占位符解析源配置
  • 环境属性必填性校验
  • 早期事件相关

obtainFreshBeanFactory

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		// 获取 BeanFactory 实例,由子类实现
		refreshBeanFactory();
		return getBeanFactory();
	}
  • refreshBeanFactory,子类实现,比如可刷新容器创建新的 BeanFactory
  • getBeanFactory,返回准备好的 BeanFactory

prepareBeanFactory

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 设置类加载器、表达式解析类、ResourceEditorRegistrar
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// ApplicationContextAwareProcessor 用来处理各种 aware 回调
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		// 忽略以下类的自动装配
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// 以下 bean 是容器默认注册的,之所以我们可以直接注入这些实例使用
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// ApplicationListenerDetector 用来 注册、移除 自定义的事件监听器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// 静态织入 相关
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 分别注册 environment systemProperties systemEnvironment 单例
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

这里是对上一个步骤获取的 BeanFactory 进行配置处理,主要是一些组件的配置和 bean 实例的注册等

  • 配置 ClassLoader StandardBeanExpressionResolver 等,StandardBeanExpressionResolverSpringSpEL 解析相关类的收口
  • 注册了 ApplicationContextAwareProcessor,这个后处理器负责 Aware 相关回调,用于给对应的示例注入 ApplicationContext Environment 等属性
  • 依赖处理相关、静态织入相关
  • 注册 ApplicationListenerDetectorenvironment systemProperties 等单例,其中我们自定义的 ApplicationListener 类型的实例会被 ApplicationListenerDetector 注册到容器中的
SpEL 相关,可以参考下文

【Spring】SpEL 二 PropertyAccessor 相关(BeanFactoryAccessor EnvironmentAccessor)

postProcessBeanFactory

	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	}

这里允许进一步对 BeanFactory 进行拓展处理,可见子类

invokeBeanFactoryPostProcessors

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// 静态织入 相关 ...
		
	}

此处是比较核心的一个步骤,关键步骤发生在 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()),它的代码较长,此处做一个总结:

  • 其中,BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor 的子类,前者是针对 BeanDefinitionRegistry 的后处理,对应方法 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry,后者是针对 BeanFactory 的后处理,对应方法 BeanFactoryPostProcessor#postProcessBeanFactory
  • 上面代码中 getBeanFactoryPostProcessors() 方法返回的是所有自行 addBeanFactoryPostProcessor,大多数情况我们不会自行添加(即便添加也是以注册 bean 组件的形式),因为这里一般为空,但如果存在,它的优先级会最高
  • 关于上述方法执行的优先级以及详细的执行顺序总结如下
  • 1)所有 自行添加BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry 方法
  • 2)所有 容器中 实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry 方法
  • 3)所有 容器中 实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry 方法
  • 4)容器中 其他 BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry 方法
  • 5)所有 自行添加BeanDefinitionRegistryPostProcessorpostProcessBeanFactory 方法
  • 6)所有 自行添加BeanFactoryPostProcessorpostProcessBeanFactory 方法
  • 7)所有 容器中 实现了 PriorityOrdered 接口的 BeanFactoryPostProcessorpostProcessBeanFactory 方法
  • 8)所有 容器中 实现了 Ordered 接口的 BeanFactoryPostProcessorpostProcessBeanFactory 方法
  • 9)容器中 其他 BeanFactoryPostProcessorpostProcessBeanFactory 方法

总结来说就是:

  • 自行添加 优先于 容器中的实例
  • BeanDefinitionRegistryPostProcessor 优先于 BeanFactoryPostProcessor
  • @PriorityOrdered 优先于 @Ordered 优先于 其他
  • postProcessBeanDefinitionRegistry 方法优先于 postProcessBeanFactory

其中,最最重要的 BeanDefinitionRegistryPostProcessor 的就是 ConfigurationClassPostProcessor,关于它的内容不少,可移步参考 Spring Configuration 专栏

registerBeanPostProcessors

	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

这里,是注册容器中所有的 BeanPostProcessor,这里不贴具体源码,简述流程:

  • 开头先注册了一个 BeanPostProcessorChecker,这个处理器主要是针对没有被所有 BeanPostProcessor 全处理的 bean(比如在这些 BeanPostProcessor 之前初始化的 bean),输出一条 info 日志
  • 然后按照如下顺序注册 BeanPostProcessor
  • 1)实现了 PriorityOrdered 接口的 BeanPostProcessor
  • 2)实现了Ordered 接口的 BeanPostProcessor
  • 3)其余的 BeanPostProcessor
  • 4)实现了 PriorityOrdered 接口的 MergedBeanDefinitionPostProcessor
  • 5)实现了Ordered 接口的 MergedBeanDefinitionPostProcessor
  • 6)其余的 MergedBeanDefinitionPostProcessor
  • 7)最后重新注册一个 ApplicationListenerDetector

initMessageSource

初始化 messageSource 属性,默认为 DelegatingMessageSource,实现国际化相关能力

关于 MessageSource(国际化),可阅读下文

【源码】关于 Spring 国际化 MessageSource

initApplicationEventMulticaster

	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		
		// 如果已经注册,则获取(创建)对应的 bean 实例
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			// ...
		}
		// 否则,创建 SimpleApplicationEventMulticaster 并注册为单例
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			// ...
		}
	}
  • 事件组播器 相关,如果不自行设置,则默认实例化一个 SimpleApplicationEventMulticaster
  • Spring 事件相关,可以参考下文:

【源码】Spring —— ApplicationEvent ApplicationListener ApplicationEventMulticaster

onRefresh

	protected void onRefresh() throws BeansException {
	}

由子类实现,比如初始化一些自定义的 bean

registerListeners

	protected void registerListeners() {
		// 注册 add 进来的监听器
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// 注册所有容器中的监听器 bean
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// ...
		
	}

监听器的注册

  • 先注册 addApplicationListener 方法添加进来的 监听器
  • 再取出容器中 ApplicationListener 类型的 bean 名称,将它们添加到 事件组播器 中
  • 值得一提的是,这个方法的工作跟之前注册的 ApplicationListenerDetector 后处理器差不多,只是此处并没有实例化这些 bean,而只是注册了对应的 beanName,但不要担心会重复监听,因为 ApplicationEventMulticaster 做了判断处理

finishBeanFactoryInitialization

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 先创建 ConversionService(如果存在)
		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));
		}
		
		// 如果没有对应的占位符(${})解析器,则由 AbstractPropertyResolver.resolvePlaceholders 解析
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// 静态织入 相关
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		beanFactory.setTempClassLoader(null);
		beanFactory.freezeConfiguration();

		// 核心步骤:非 Lazy 单例注册
		beanFactory.preInstantiateSingletons();
	}
  • 如果我们有自定义 ConversionService,这个地方就会注册进去,作为 beanFactory 的标准转换服务
  • 如果没有指定值解析器,则此处委托给 EnvironmentEnvironment 的相关文章有提到,此处的调用链实际是 Environment -> PropertySourcesPropertyResolver -> PropertyPlaceholderHelper
  • 静态织入相关,略
  • 最后就是最关键的步骤,非 Lazy 单例的初始化,此方法详情可参考文章:

【源码】Spring —— BeanFactory 解读 5 DefaultListableBeanFactory

finishRefresh

至此,主要的步骤都完了,该方法执行:

  • Lifecycle 相关
  • 发布 ContextRefreshedEvent 事件

resetCommonCaches

最后一步,各种缓存清除

总结

归纳一下这章节的内容,我们平时开发过程中可能不会陌生的点:

  • 了解到 Aware 感知回调接口机制及时机
  • 比较关键的一个点:BeanFactoryPostProcessor 的执行时机及顺序,这对于我们进行 BeanDefinition BeanFactory 相关拓展十分有用,参考 ConfigurationClassPostProcessor
  • 同样的,BeanPostProcessor 的执行时机与顺序也十分重要,虽然本文并没有详细讲述时机与顺序(但在前后的章节中有详细讲述),如果要依此对 bean 实例进行自定义的拓展,了解它们是必须的
  • 国际化相关,如果业务涉及便可深入了解
  • 事件驱动相关,这其实是个独立且重要的模块,首先 事件驱动 本身就是一种重要的思想,我们完全可以记住 Spring 的实现进行自定义的使用与拓展,比如 SpringBoot 就完美的应用了事件机制
  • 监听器 的注册,了解自定义的监听器是何时、如何被注册进容器的
  • 最后就是距离我们最近的东西:单例初始化,到容器伊始的 BeanDefinition 收集,到中期可能的 BeanDefinition 新增、变更,到该阶段基于 BeanDefinition 构造 bean 实例与后处理等一系列繁杂的过程

上一篇:【Spring】ApplicationContext 一 接口梳理

下一篇:【Spring】ApplicationContext 三 AnnotationConfigApplicationContext

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值