Spring 5 ApplicationContext#refresh() -- 深入源码解析(一)

相关源码注释

ApplicationContext

Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释

BeanFactory

Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释

在Spring的众多 ApplicationContext 实现类最终的 refresh(),还是 AbstractApplicationContext 实现主体代码,附加功能基本都是在onRefresh() 上附加。

所以我直接围绕 AbstractApplicationContext 的 refresh() 进行解析。

Spring 5 ApplicationContext#refresh() – 深入源码解析(一)
Spring 5 ApplicationContext#refresh() – 深入源码解析(二)

AbstractApplocationContext.refresh

@Override
	public void refresh() throws BeansException, IllegalStateException {
    
    
		//同步,startupShutdownMonitor只是一个普通的object对象,
		synchronized (this.startupShutdownMonitor) {
    
    
			// Prepare this context for refreshing.
			// 准备该上下文的刷新
			// p:准备该上下文以进行刷新,设置其启动日期和activie标记以及
			// 	执行属性源的任何 初始化。还有监听器都初始化
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 告诉子类刷新新内部bean工厂
			//对此上下文的基础bean工厂进行实际刷新,关闭前一个bean工厂(如果有),
			// 并为上下文生命周期的下一个阶段初始化一个新的bean工厂,并使用XmlBeanDefinitionReader
			// 将bean定义加载给bean工厂中
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 准备这种情况下使用的bean工厂
			prepareBeanFactory(beanFactory);

			try {
    
    
				// Allows post-processing of the bean factory in context subclasses.
				// 允许在上下文子类中对bean工厂进行后处理
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 调用在上下文中注册为bean的工厂处理器
				// 实例化并调用所有注册BeanFactoryPostProcess bean,并遵从显式顺序(如果给定的话)
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 注册拦截Bean创建的 BeanPostProcessor
				// 实例化和注册所有 BeanPostProcessor 类型的Bean对象,如果给定的话,遵循显示顺序.
				// 必须在应用程序Bean的任何实例化之前调用
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 为此上下文初始化消息源
				// 从当前BeanFactory中获取名为 'messageSource' 的 MessageSource 类型的Bean对象,如果没有找到,就创建 一个
				// DelegatingMessageSource 对象作为该上下文的 messageSource 属性值,并将该上下文的 messageSource 注册到 该
				// 上下文的BeanFactory中。
				// 默认对该上下文的messageSource设置父级messageSource,父级messageSource为父级上下文的messageSoure属性对象
				// 或者父级上下文本身
				initMessageSource();

				// Initialize event multicaster for this context.
				// 为此上下文初始化事件多播器
				// 从从beanFactory中获取名为 'applicationEventMulticaster' 的 ApplicationEventMulticaster 类型的Bean对象,
				// 引用到 该上下文的 applicationEventMulticaster 属性,如果获取不到,就新建一个
				// SimpleApplicationEventMulticaster 实例 引用 到 上下文的 applicationEventMulticaster 属性 中
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 初始化特定上下文子类中的其他特殊Bean
				onRefresh();

				// Check for listener beans and register them.
				// 检查监听器Bean并注册它们
				//注册静态指定的监听器和beanFactory内的监听器Bean对象【不会导致监听器Bean对象实例化,仅记录其Bean名】到当前上
				// 	下文 的多播器,然后发布在多播程序设置之前发布的ApplicationEvent集到各个监听器中
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.`
				// 实例化所有剩余的(非延迟初始化)的单例
				//完成这个上下文BeanFactory的初始化,初始化所有剩余的 单例(非延迟初始化) Bean对象
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// 最后一步:发布相应的事件
				// 	1. 清空在资源加载器中的所有资源缓存
				//	2. 初始化 LifecycleProcessor.如果上下文中找到 'lifecycleProcessor' 的 LifecycleProcessor Bean对象, 则使用 DefaultLifecycleProcessor
				//	3. 将刷新传播到生命周期处理器
				//	4. 新建 ContextRefreshedEvent 事件对象,将其发布到所有监听器。
				//	5. 注册 当前上下文 到 LiveBeansView,以支持 JMX 服务
				finishRefresh();
			}

			catch (BeansException ex) {
    
    //捕捉在初始化Bean时抛出的 Bean异常
				//如果当前日志级别时 警告
				if (logger.isWarnEnabled()) {
    
    
					// 在上下文初始化过程中遇到异常 - 尝试取消刷新
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				// 销毁已经创建的单例,以避免悬空资源
				//  默认实现此上下文中销毁所有缓存的单例,调用DisposableBean.destroy()和 或指定的'destory-method'
				destroyBeans();

				// Reset 'active' flag.
				// 重置 '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...
				// 在 Spring的核心中重置常见的自省缓存,因为我们可能不再需要单例Bean的元数据了。
				//删除ReflectionUtils,AnnotationUtils,ResolvableType的缓存,清除当前的类加载器的自省缓存,
				// 	删除该类加载器下 所有类的自省结果,并从接受列表中删除类加载器(及其子类)
				resetCommonCaches();
			}
		}
	}

###prepareRefresh();

/**
	 * <p>ApplicationContext刷新前的准备工作</p>
	 * Prepare this context for refreshing, setting its startup date and
	 * active flag as well as performing any initialization of property sources.
	 * <p>准备该上下文以进行刷新,设置其启动日期和activie标记以及执行属性源的任何
	 * 初始化。</p>
	 */
	protected void prepareRefresh() {
    
    
		// Switch to active. 切换到互动状态
		//p:设置上下文启动时的系统时间
		this.startupDate = System.currentTimeMillis();
		//p:设置上下文为不关闭状态,该变量是线程安全的
		this.closed.set(false);
		///p:设置上下文为活动状态,该变量是线程安全的
		this.active.set(true);

		//根据日志级别打印日志
		if (logger.isDebugEnabled()) {
    
    
			if (logger.isTraceEnabled()) {
    
    
				logger.trace("Refreshing " + this);
			}
			else {
    
    
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		// 在上下文环境中初始化任何占位符属性源
		//p:这个一个钩子方法,用于交由子类替换任何存根属性源
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		// 验证所有标记为必须的属性都是可解析的,请参见
		// 			ConfigurablePropertyResolver#setRequiredProperties方法,
		// 			p:该方法的默认实现是AbstractPropertyResolver类
		// p:只是验证要必须要有的属性不会为null,验证不通过会抛出MissingRequiredPropertiesException
		// SpringBoot默认情况下不存在必要的属性
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners... 存储预刷新的ApplicationListeners
		// p:初始化earlyApplicationListeners
		if (this.earlyApplicationListeners == null) {
    
    
			//p:LinkedHashSet是Set集合的一个实现,具有set集合不重复的特点,同时具有
			// 可预测的迭代顺序,也就是我们插入的顺序,并且linkedHashSet是一个非线程安全的集合。
			// 如果有多个线程同时访问当前linkedhashset集合容器,并且有一个线程对当前容器中的元素
			// 做了修改,那么必须要在外部实现同步保证数据的冥等性
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
    
    
			// Reset local application listeners to pre-refresh state.
			// 将本地应用程序监听器重置为预刷新状态
			// p:清空静态指定的监听器集
			this.applicationListeners.clear();
			// p:将 刷新之前已注册本地侦听器 全部添加到静态指定的监听器集中
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		// 允许收集早期的ApplicationEvents,一旦多播器可用就发布
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

ApplicationContext刷新前的准备工作:

  1. 设置上下文启动时的系统时间,startupDate
  2. 设置上下文为不关闭状态,closed
  3. 设置上下文为活动状态,active
  4. 根据日志级别打印日志,提示准备刷新ApplicationContext
  5. 创建Environment对象,默认情况下Environment对象是StandardEnvironment对象
  6. 提供一个钩子方法,交由子类替换任何存根属性源。默认情况下子类GenericWebApplicationContext, 通过该方法设置sources中的servletContextInitParams和servletConfigInitParams属性,以供更方便的 形式获取SerlvetContext。
  7. 初始化用于存储已注册本地侦听器的LinkedHashSet集合,earlyApplicationListeners
  8. 初始化用于收集早期的ApplicationEvents的LinkeHashSet集合,earlyApplicationEvents

obtainFreshBeanFactory()

   /**
    * <p>
    *     获取新的Bean工厂
    * </p>
    * Tell the subclass to refresh the internal bean factory.
    * <p>告诉子类刷新内部bean工厂。</p>
    * @return the fresh BeanFactory instance --新的BeanFactorty实例
    * @see #refreshBeanFactory()
    * @see #getBeanFactory()
    */
   protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    
    
   	//调用子类实现方法执行实际的配置加载
   	refreshBeanFactory();
   	//返回子类提供的Bean工厂,
   	return getBeanFactory();
   }

获取新的Bean工厂:

  1. 调用供子类实现refreshBeanFactory()方法执行实际的配置加载
  2. 调用供子类实现的getBeanFactory()方法获取子类提供的Bean工厂

Spring 5 ApplicationContext#refresh() – obtainFreshBeanFactory()源码解析

prepareBeanFactory(beanFactory)

	/**
	 * <p>对bean工厂做准备工作:
	 * </p>
	 * Configure the factory's standard context characteristics,
	 * such as the context's ClassLoader and post-processors.
	 * <p>配置工厂的标准上下文特征,例如上下文的ClassLoader和后处理器。</p>
	 * @param beanFactory the BeanFactory to configure -- 要配置的BeanFactory
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    
    
		// Tell the internal bean factory to use the context's class loader etc.
		// 告诉内部bean工厂使用上下文的类加载器等
		//设置beanFactory的bean的类加载器,通常是当前线程的上下文类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
		//为bean定义值中的表达式指定解析策略,这里设置的是标准的Spring EL表达式解析器
		//StandardBeanExpressionResolver:用于解析SpEL表达式的解析器
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//添加属性编辑器到bean工厂,ResourceEditorRegistrar:属性编辑器的注册器,里面默认提供了一下简单通用常用类型的属性编辑器
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		//使用上下文回调配置Bean工厂
		//为bean工厂添加ApplicationContextAwareProcessor
		//ApplicationContextAwareProcessor:一个Spring内部工具,它实现了接口BeanPostProcessor,用于向实现了如下某种Aware接口
		// 	的bean设置ApplicationContext中相应的属性:EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware
		//	ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware,
		//	如果bean实现了以上接口中的某几个,那么这些接口方法调用的先后顺序就是上面接口排列的先后顺序。
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		//忽略 EnvironmentAware 依赖接口进行自动装配
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		//忽略 EmbeddedValueResolverAware 依赖接口进行自动装配
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		//忽略 ResourceLoaderAware 依赖接口进行自动装配
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		//忽略 ApplicationEventPublisherAware 依赖接口进行自动装配
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		//忽略 MessageSourceAware 依赖接口进行自动装配
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		//忽略 ApplicationContextAware 依赖接口进行自动装配
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// BeanFactory接口未在普通工厂中注册为可解析类型
		// MessageSource registered (and found for autowiring) as a bean.
		// MessageSource注册为Bean(并发现用于自定装配)
		//用beanFactory对象注册一个BeanFactory类型
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		//用本类对象注册一个ResourceLoader类型
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		//用本类对象注册一个ApplicationEventPublisher类型
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		//用本类对象注册一个ApplicationContext类型
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// 注册早期的后处理器以将内部bean检测为ApplicationListeners
		// ApplicationListenerDetector:该BeanPostProcessor检测那些实现了接口ApplicationListener的bean,在它们创建时初始化之后,
		// 将它们添加到应用上下文的事件多播器上;并在这些ApplicationListener bean销毁之前,
		// 将它们从应用上下文的事件多播器上移除。
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// 标记1 - start
		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		// 如果发现LoadTimeWeaver,请准备编制
		// 	beanFactory.containBean除了检查bean对象是否存在,还可以判断BeanDefinition对象是否存在,存在一样会返回true。
		//			所以这里是是检查有没有loadTimeWeaver的BeanDefinition对象
		// SpringBoot默认情况下该bean工厂不包含loadTimeWeaver的bean定义或外部注册的singleton实例
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    
    
			//LoadTimeWeaverAwareProcessor只是用实现了LoadTimeWeaverAware接口的bean
			//			// 			回调LoadTimeWeaverAware.setLoadTimeWeaver(LoadTimeWeaver)方法
			//			// 参考博客:https://blog.csdn.net/weixin_34112208/article/details/89750308
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			//设置一个临时的ClassLoader以进行匹配
			//ContextTypeMatchClassLoader:该类加载器破坏了双亲委派机制,除指定排除类外,
			// 	对每个调用loadClass的类,都会新建一个ContextOverridingClassLoader类加载器进行
			// 加载,并对每个类的字节缓存起来,以便在父类ClassLoader中拾取 最近加载的类型
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
		// 标记1 - end

		// Register default environment beans. - 注册默认的环境bean
		//如果bean工厂中没有包含名为'environment'的bean,(忽略在祖先上下文定义的bean)
		//SpringBoot默认情况下该bean工厂是否包含loadTimeWeaver的bean定义或外部注册的singleton实例
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
    
    
			//获取该ApplicationContext的环境对象,注册到bean工厂中,命名为'environment'
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		//如果bean工厂中没有包含名为'systemProperties'的bean,(忽略在祖先上下文定义的bean)
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
    
    
			//获取该ApplicationContext的环境对象的系统属性Map,注册到bean工厂中,命名为'systemProperties'
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		//如果bean工厂中没有包含名为'systemEnvironment'的bean,(忽略在祖先上下文定义的bean)
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
    
    
			//获取该ApplicationContext的环境对象的系统环境属性Map,注册到bean工厂中,命名为'systemProperties'
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

对bean工厂做准备工作:

  1. 设置beanFactory的bean的类加载器,通常是当前线程的上下文类加载器,AppClassLoader
  2. 为bean定义值中的表达式指定解析策略,这里设置的是标准的Spring EL表达式解析器,StandardBeanExpressionResolver
  3. 添加属性编辑器到bean工厂,ResourceEditorRegistrar
  4. 为bean工厂添加 为实现了某种Aware接口的bean设置ApplicationContext中相应的属性的BeanPostProcessor,ApplicationContextAwareProcessor
  5. 忽略EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware ApplicationContextAware依赖接口进行自动装配
  6. 添加自动装配对象:BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext
  7. 如果该bean工厂包含具有给定名称的BeanDefinition对象或外部注册的singleton实例,会添加用于回调LoadTimeWeaverAware#setLoadTimeWeaver(LoadTimeWeaver) 方法的BeanPostProcessor,以及设置一个ContextTypeMatchClassLoader的临时类加载器用于对每个调用loadClass的类【除指定排除类外】,都会新建一个 ContextOverridingClassLoader类加载器进行加载,并对每个类的字节缓存起来,以便在父类ClassLoader中拾取 最近加载的类
  8. 注册environment,systemProperties,systemEnvironment单例对象到该工厂

Spring 5 ContextTypeMatchClassLoader 源码分析

postProcessBeanFactory(beanFactory);

/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for registering special
	 * BeanPostProcessors etc in certain ApplicationContext implementations.
	 * <p>标准初始化后,修改应用程序上下文的内部bena工厂。所有bean定义都将被加载,
	 * 但尚未实例化任何bean。这允许在某些ApplicationContext实现中注册特殊的
	 * BeanPostProcessor</p>
	 * @param beanFactory the bean factory used by the application context
	 *                    - 应用程序上下文使用的bean工厂
	 */
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    
    
	}

这里仅分析SpringBoot所用到的 GenericApplicationContext 实现

/**
	 * Register ServletContextAwareProcessor.
	 * <p> 注册 ServletContextAwareProcessor </p>
	 * @see ServletContextAwareProcessor
	 */
	@Override
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    
    
		if (this.servletContext != null) {
    
    
			//ServletContextAwareProcessor:将ServletContext,servletConfig 传递给实现ServletContextAware,
			// 		ServletConfigAware接口的bean的BeanPostProcessor实现
			beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
			//忽略ServletContextAware进行自动装配
			beanFactory.ignoreDependencyInterface(ServletContextAware.class);
		}
		//用beanFactory注册特定于web的范围("request", "session", "globalSession", "application") ,
		// 	就像WebApplicationContext所使用的那样。
		WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
		//向给定的BeanFactory注册特定于Web的环境Bean ("contextParameters", "contextAttributes"),
		// 	就像 WebApplicationContext 所使用的那样
		WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
	}

invokeBeanFactoryPostProcessors(beanFactory)

/**
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>实例化并调用所有注册BeanFactoryPostProcess bean,并遵从显式顺序(如果给定的话)</p>
	 * <p>Must be called before singleton instantiation.
	 * <p>必须在单例实例化之前调用</p>
	 */
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    
    
		//回调 BeanFactoryPostPorcessors 和 beanFactory的所有BeanFactoryPostProcessor对象的回调方法
		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)
		// 检测LoadTimeWeaver并准备编织(如果在此期间发现)
		// (e.g. 通过 ConfigurationClassPostProcessor注册@Bean方法)
		//如果bean工厂没有设置临时类加载器 且 'loadTimeWeaver' 不存在于bean工厂中
		// 下面的代码其实跟prepareBeanFactory方法的标记1的代码一样,应该是因为该方法的上一个步是供给子类重写的钩子方法,
		// Spring开发人担心经过上一步的处理后,会导致'loadTimeWeaver'被玩坏了,所有才
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    
    
			//LoadTimeWeaverAwareProcessor只是用实现了LoadTimeWeaverAware接口的bean
			// 			回调LoadTimeWeaverAware.setLoadTimeWeaver(LoadTimeWeaver)方法
			// 参考博客:https://blog.csdn.net/weixin_34112208/article/details/89750308
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			//ContextTypeMatchClassLoader:该类加载器破坏了双亲委派机制,除指定排除类外,
			// 	对每个调用loadClass的类,都会新建一个ContextOverridingClassLoader类加载器进行
			// 加载,并对每个类的字节缓存起来,以便在父类ClassLoader中拾取 最近加载的类型
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

Spring 5 PostProcessorRegistrationDelegate 源码解析

registerBeanPostProcessors(beanFactory)

/**
	 * Instantiate and register all BeanPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>实例化和注册所有 BeanPostProcessor 类型的Bean对象,如果给定的话,遵循显示顺序</p>
	 * <p>Must be called before any instantiation of application beans.
	 * <p>必须在应用程序Bean的任何实例化之前调用</p>
	 */
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    
    
		//注册 BeanPostProcessors 到 beanFactory 中
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

Spring 5 PostProcessorRegistrationDelegate 源码解析

initMessageSource()

/**
	 * Initialize the MessageSource.
	 * Use parent's if none defined in this context.
	 * <p>初始化 MessageSource.</p>
	 * <p>如果在此上下文中没有定义,则使用父级的</p>
	 */
	protected void initMessageSource() {
    
    
		//MessageSource:用于解析消息的策略界面,支持此类消息参数化和国际化
		//获取当前上下文的BeanFactory对象
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//如果本地BeanFactory包含messageSource的bean,忽略父工厂
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
    
    
			//从beanFactory中获取名为 'messageSource' 的 MessageSouce 类型的Bean对象
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			// 使 MessageSource 知道 父 MessageSouce
			// HierarchicalMessageSource:MessageSource 的子接口,由能分层解析消息的对象实现
			// 如果 parent 不为 null && messageSource 是 HierarchicalMessageSource 对象
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
    
    
				//强转 messageSource 为 HierarchicalMessageSource 对象
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				//获取 hms 的 MessageSource 的父级 MessageSource 对象
				if (hms.getParentMessageSource() == null) {
    
    
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					// 如果还没有注册 父级 MessageSource,只能将父级上下文设置父级 MessageSource
					// 获取父级上下文的 MessageSource 对象,将其设置 hms 的 父级 MessagoueSource 对象
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			//如果当前跟踪日志级别
			if (logger.isTraceEnabled()) {
    
    
				// 使用 MessageSource [messageSource]
				logger.trace("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
    
    //没有在beanFactory中找到'messageSource'Bean对象时
			// Use empty MessageSource to be able to accept getMessage calls.
			// 使用 空的 MessageSource 来能够接收 getMessage 调用
			DelegatingMessageSource dms = new DelegatingMessageSource();
			// 获取父级上下文的 MessageSource 对象,将其设置 hms 的 父级 MessagoueSource 对象
			dms.setParentMessageSource(getInternalParentMessageSource());
			//设置当前上下文的 messageSource 为 dms
			this.messageSource = dms;
			//将'messageSource'与 messageSource 注册到 beanFactory 中
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			//如果当前是跟踪日志级别
			if (logger.isTraceEnabled()) {
    
    
				//没有名为'messageSource'的对象,使用 messageSource
				logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
			}
		}
	}

初始化 MessageSource
从当前BeanFactory中获取名为 ‘messageSource’ 的 MessageSource 类型的Bean对象,如果没有找到,就创建 一个 DelegatingMessageSource 对象作为该上下文的
默认对该上下文的messageSource设置父级messageSource,父级messageSource为父级上下文的messageSoure属性对象 或者父级上下文本身

篇幅过长,请看下一篇

Spring 5 ApplicationContext#refresh() – 深入源码解析(二)

猜你喜欢

转载自blog.csdn.net/qq_30321211/article/details/108321911