Spring Context初始化流程(源码分析)

  时间:2020-08-03 12:33:03  阅读量:38  评论数:0  作者:⁢⁢⁢ 

⁢⁢⁢ 分享了SpringContext初始化流程(源码分析),无论新手学习还是老手做项目,都可以参考其源码分析改造,是一篇有价值的文章。

不管是XML配置的Context,还是Spring Boot的Context,还是Web服务中的Context,创建后都会调用AbstractApplicationContext类的refresh()方法。

定位到AbstractApplicationContext下的refresh()方法,开始分析。
整体流程如下:


	@Override
	public void refresh() throws BeansException, IllegalStateException {
		//1
		synchronized (this.startupShutdownMonitor) {
			//2
			prepareRefresh();
			//3
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//4
			prepareBeanFactory(beanFactory);

			try {
				//5
				postProcessBeanFactory(beanFactory);

				//6
				invokeBeanFactoryPostProcessors(beanFactory);

				//7
				registerBeanPostProcessors(beanFactory);

				//8
				initMessageSource();

				//9
				initApplicationEventMulticaster();

				//10
				onRefresh();

				//11
				registerListeners();

				// 12
				finishBeanFactoryInitialization(beanFactory);

				// 13
				finishRefresh();
			}

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


				destroyBeans();

				cancelRefresh(ex);

				throw ex;
			}

			finally {
				//14
				resetCommonCaches();
			}
		}
	}

分为14步,接下来我们一步一步来进行分析。

1.
synchronized (this.startupShutdownMonitor) 加锁,确保了同一时间startupShutdownMonitor的状态不发生改变。
2.
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());
			}
		}
		//初始化Context环境占位符
		initPropertySources();

		// 动作根据子类的自求由子类执行,然后验证是否缺失必要的properties
		getEnvironment().validateRequiredProperties();

		// 存储预刷新的ApplicationListeners
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// 将本地应用程序侦听器重置为预刷新状态。
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		//允许收集早期的ApplicationEvent 一旦多播器可用时就发布
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

3.
刷新并获得内部的 Bean Factory

4.
进入方法prepareBeanFactory()

/**
	 * 配置工厂的标准上下文特征,例如上下文的ClassLoader和后处理器
	 * @param beanFactory the BeanFactory to configure
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 告诉内部bean工厂使用上下文的类加载器等
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// 使用上下文回调配置Bean工厂
		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);

		//BeanFactory接口未在普通工厂中注册为可解析类型
		//MessageSource注册为Bean(并发现用于自动装配)
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		//注册早期的后处理器以将内部bean检测为ApplicationListeners。
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		//检测LoadTimeWeaver并准备编织(如果找到)
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			//设置一个临时的ClassLoader以进行类型匹配。
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		//注册默认环境bean
		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。

5.
postProcessBeanFactory方法源码如下

/**
	 * 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.
	 * @param beanFactory the bean factory used by the application context
	 */
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	}

为 Context 的子类提供后置处理 BeanFactory 的扩展能力。如果子类想在 Bean 定义加载完成后,开始初始化上下文之前做一些特殊逻辑,可以复写这个方法。

6.
invokeBeanFactoryPostProcessors()方法源码如下:

	/**
	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before singleton instantiation.
	 */
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	//传入Bean工厂并获取容器中的Bean工厂后置处理器(注意这里Bean工厂后置处理器还没有初始化)
		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()));
		}
	}

执行 Context 中注册的 Bean Factory 后缀处理器。这里有两种后置处理器,一种是可以注册 Bean 的后缀处理器,另一种是针对 BeanFactory 进行处理的后置处理器。执行的顺序是,先按优先级执行可注册 Bean 的处理器,在按优先级执行针对 BeanFactory的处理器。由 ConfigurationClassPostProcessor 触发、由ClassPathBeanDefinitionScanner 解析并注册到 BeanFactory。

7.
registerBeanPostProcessors方法源码如下

	/**
	 * Instantiate and register all BeanPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before any instantiation of application beans.
	 */
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

按优先级指定顺序在 BeanFactory 中注册 Bean的后缀处理器,Bean 后置处理器可以在 Bean 初始化前、后执行处理。

8.
initMessageSource方法源码如下:

	/**
	 * 实例化消息源
	 * 如果在此上下文中未定义父项,则使用父项
	 */
	protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Using MessageSource ["   this.messageSource   "]");
			}
		}
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isTraceEnabled()) {
				logger.trace("No '"   MESSAGE_SOURCE_BEAN_NAME   "' bean, using ["   this.messageSource   "]");
			}
		}
	}

初始化消息源,消息源用来支持消息的国际化

9.

	/**
	 *初始化应用事件广播器
	 *如果上下文中未定义则用简单的应用事件广播器
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 */
	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()   "]");
			}
		}
	}

初始化应用事件广播器。事件广播器用来向 ApplicationListener 通知各种应用产生的事件,是一个标准的观察者模式。

10.
onRefresh方法源码如下

	/**
	 * Template method which can be overridden to add context-specific refresh work.
	 * Called on initialization of special beans, before instantiation of singletons.
	 * <p>This implementation is empty.
	 * @throws BeansException in case of errors
	 * @see #refresh()
	 */
	protected void onRefresh() throws BeansException {
		//对于子类:默认情况下不执行任何操作。
	}

是留给子类的扩展步骤,用来让特定的 Context 子类初始化其他的 Bean。

11.
registerListeners方法源码如下:

/**
	 * 添加将ApplicationListener实现为侦听器的bean
	 * 不会影响其他侦听器,可以将它们添加为非bean.
	 */
	protected void registerListeners() {
		//首先注册静态指定的侦听器
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		//不要在这里初始化FactoryBeans:我们需要保留所有常规bean
		//未初始化,以使后处理器适用于它们!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		//现在我们终于有了一个多播器,可以发布早期的应用程序事件
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

把实现了 ApplicationListener 的 Bean 注册到事件广播器,并对广播器中的早期未广播事件进行通知。

12.
finishBeanFactoryInitialization方法源码如下:

/**
	 *完成此上下文的Bean工厂的初始化
	 *初始化所有剩余的单例beans.
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		//为此上下文初始化转换服务
		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));
		}

		//如果之前没有任何bean后处理器(例如PropertyPlaceholderConfigurer bean)注册过以下任何一个,则注册一个默认的嵌入式值解析器:
		//此时,主要是为了注释属性值中的解析。
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		//尽早初始化LoadTimeWeaverAware Bean,以便尽早注册其转换器。
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		//停止使用临时ClassLoader进行类型匹配。
		beanFactory.setTempClassLoader(null);

		//允许缓存所有bean定义元数据,而不期望进一步的更改。
		beanFactory.freezeConfiguration();

		//实例化所有剩余的(非延迟初始化)单例。
		beanFactory.preInstantiateSingletons();
	}

冻结所有 Bean 描述信息的修改,实例化非延迟加载的单例 Bean。

13.
finishRefresh方法源码如下:

/**
	 *完成此上下文的刷新,调用LifecycleProcessor的 onRefresh()方法并发布
	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
	 */
	protected void finishRefresh() {
		//清除上下文级别的资源缓存(例如来自扫描的ASM元数据)。
		clearResourceCaches();

		// 为此上下文初始化生命周期处理器。
		initLifecycleProcessor();

		//首先将刷新传播到生命周期处理器。
		getLifecycleProcessor().onRefresh();

		//发布最终事件。
		publishEvent(new ContextRefreshedEvent(this));

		// 如果活动,请参加LiveBeansView MBean。
		LiveBeansView.registerApplicationContext(this);
	}

完成上下文的刷新工作,调用 LifecycleProcessor 的 onFresh() 方法以及发布 ContextRefreshedEvent 事件。

14.

/**
	 * Reset Spring's common reflection metadata caches, in particular the
	 * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType}
	 * and {@link CachedIntrospectionResults} caches.
	 * @since 4.2
	 * @see ReflectionUtils#clearCache()
	 * @see AnnotationUtils#clearCache()
	 * @see ResolvableType#clearCache()
	 * @see CachedIntrospectionResults#clearClassLoader(ClassLoader)
	 */
	protected void resetCommonCaches() {
		ReflectionUtils.clearCache();
		AnnotationUtils.clearCache();
		ResolvableType.clearCache();
		CachedIntrospectionResults.clearClassLoader(getClassLoader());
	}

重置公共的缓存,比如 ReflectionUtils 中的缓存、 AnnotationUtils ,ResolvableType中的缓存等等;

到此文章就结束了。

关键词:spring,java,context,初始,初始化,流程,源码,分析