spring 源码分析 应用上下文刷新 (AbstractApplicationContext#refresh方法)

这章我们分析 spring 核心方法refresh(), Spring容器的创建刷新过程。 这个方法在 spring 中有着很重要的功能处理下面我们来分析:

AbstractApplicationContext # refresh() 方法分析

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 1、准备刷新上下文。
			prepareRefresh();

			// 2、获取Bean工厂。
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 3、Bean工厂准备。
			prepareBeanFactory(beanFactory);

			try {
				// 4、后置处理 Bean工厂。 (由子类具体实现)
				postProcessBeanFactory(beanFactory);
				
				// 5、执行 BeanFactoryPostProcessor 处理 Bean工厂
				invokeBeanFactoryPostProcessors(beanFactory);

				// 6、通过当前上下文获取 BeanPostProcessor 注册给当前 Bean工厂
				registerBeanPostProcessors(beanFactory);

				// 7、初始化消息资源器
				initMessageSource();

				// 8、初始化应用事件广播 (SimpleApplicationEventMulticaster)
				initApplicationEventMulticaster();

				// 9、留给子类重写, 初始化主题资源. 主要用于如何定位相应的主题资源文件 (ThemeSource) 
				onRefresh();

				// 10、向广播器中心注册应用监听器, (ApplicationEventMulticaster) 添加(ApplicationListener)
				registerListeners();

				// 11、完成BeanFactory初始化. 1)设置转换服务.  2)关闭对BeanDefinition操作. 3)实例化(非延迟初始化)单例
				finishBeanFactoryInitialization(beanFactory);

				// 12、完成刷新 (a、清空资源缓存 b、初始化 LifecycleProcessor 生命周期处理器并调用 onRefresh() d、发布    ContextRefreshedEvent 上下文刷新事件 )
				finishRefresh();
			}

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

				// a\如果异常, 则销毁已经创建的单例,以避免悬空资源。 b\并重置“活跃”的旗帜为false
				destroyBeans();
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// 13、清除缓存. 重置Spring内核中的常见自省缓存,因为我们可能再也不需要单例bean的元数据了……
				resetCommonCaches();
			}
		}
	}
1、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());
			}
		}

		// Initialize any placeholder property sources in the context environment
		// 在上下文环境中初始化任何占位符属性源   空实现
		initPropertySources();

		// Validate that all properties marked as required are resolvable
		// see ConfigurablePropertyResolver#setRequiredProperties
		//获取上下文中的环境效验请求属性
		getEnvironment().validateRequiredProperties();

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		//创建应用事件Set集合, 用于提前公布
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}
2、obtainFreshBeanFactory() 获取BeanFactory
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory(); //抽象方法
		return getBeanFactory();
	}
	
	protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {  //判断是否存在,如存在就销毁,关闭
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory(); //初始化 DefaultListableBeanFactory
			beanFactory.setSerializationId(getId());
			//定制 BeanFactory (设置是否允许 BeanDefinition 覆盖, 是否允许循环引用)
			customizeBeanFactory(beanFactory);
			//创建 XmlBeanDefinitionReader 对象用来解析xml, 并加载bean
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

3、prepareBeanFactory(beanFactory) BeanFactory的准备工作
	/**
	 * 配置工厂的标准上下文特征,例如上下文的类加载器和后处理器。
	 * 一、配置类加载器
	 * 二、配置表达式分解器
	 * 三、添加属性编辑注册器
	 * 四、添加后置处理器
	 * 五、忽视依赖接口
	 * 六、注册分解器依赖
	 * 七、注册单列
	 */
	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 设置Bean的类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
		// 设置Bean表达式分解器
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		// 给BeanFactory添加属性编辑注册器
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		// 添加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 interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		// 注册可用于分解的依赖
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); //BeanFactory
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		// 添加Bean后置处理器 ApplicationListenerDetector
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		// 注册默认环境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());
		}
	}
4、postProcessBeanFactory(beanFactory) BeanFactory后置处理 留给子类重写
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	}
	// 子类重写 AbstractRefreshableWebApplicationContext
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
		beanFactory.ignoreDependencyInterface(ServletContextAware.class);
		beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

		WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
		WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
	}
5、invokeBeanFactoryPostProcessors(beanFactory) 执行BeanFactory后置方法
	/**
	 * 实例化和调用所有已注册的BeanFactoryPostProcessor bean,如果给定了显式顺序,则尊重显式顺序。
	 * 一、处理器注册代理处理所有的BeanFactory处理器
	 * 二、给BeanFactory添加处理器
	 * 三、设置临时类加载器
	 */
	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		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()));
		}
	}
6、registerBeanPostProcessors(beanFactory) 注册bean的后置处理器
	/**
	 * 实例化和调用所有已注册的BeanPostProcessor bean,如果给定了显式顺序,则尊重显式顺序。
	 */
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
7、initMessageSource() 初始化MessageSource组件
	/**
	 * 初始化MessageSource
	 */
	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 + "]");
			}
		}
	}
8、initApplicationEventMulticaster() 初始化事件广播器
	/**
	 * 初始化ApplicationEventMulticaster 事件广播器
	 */ 
	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 {
			// 创建广播器 SimpleApplicationEventMulticaster
			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() + "]");
			}
		}
	}
9、onRefresh() 留给子类重写
	/**
	 * 模板方法,该方法可被重写以添加特定于上下文的刷新工作。
	 * 在实例化单例之前对特殊bean进行初始化时调用。
	 */
	protected void onRefresh() throws BeansException {
		// For subclasses: do nothing by default.
	}
	// 子类实现 AbstractRefreshableWebApplicationContext
	protected void onRefresh() {
		this.themeSource = UiApplicationContextUtils.initThemeSource(this);
	}
10、registerListeners() 注册事件监听器
	/**
	 * 添加实现ApplicationListener为侦听器的bean。不影响其他侦听器,这些侦听器可以在不使用bean的情况下添加。
	 * 一、遍历监听器集合, 添加一个侦听器来接收所有事件的通知。
	 * 二、根据class 得到所有的实现类的名称, 并添加一个侦听器bean来接收所有事件的通知。
	 * 三、发布早期的应用程序事件, 将给定的应用程序事件多播到适当的侦听器
	 */
	protected void registerListeners() {
		// Register statically specified listeners first.
		// 遍历监听器集合
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			// 添加一个侦听器来接收所有事件的通知。
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		// 根据class 得到所有的实现类的名称
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			// 添加一个侦听器bean来接收所有事件的通知。
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		// 发布早期的应用程序事件
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				// 将给定的应用程序事件多播到适当的侦听器
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}
11、finishBeanFactoryInitialization(beanFactory) 初始化所有剩下的单实例bean
	/**
	 * 结束此上下文的bean工厂的初始化,初始化所有剩余的单例bean。
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 是否包含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));
		}

		// 如果没有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);
		}

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

		// 冻结所有BeanDefinition
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 实例化所有剩余的(非延迟初始化)单例。
		beanFactory.preInstantiateSingletons();
	}
12、finishRefresh() 容器创建完成
	/**
	 * 完成此上下文的刷新,调用LifecycleProcessor的onRefresh()方法并发布
	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
	 */
	protected void finishRefresh() {
		// Clear context-level resource caches (such as ASM metadata from scanning).
		//清空资源缓存
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
		// 初始化生命周期处理器
		initLifecycleProcessor();

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

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

		// 注册应用上下文
		LiveBeansView.registerApplicationContext(this);
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章