spring启动之ApplicationContext-refresh流程

什么是ApplicationContext

在上一篇我们一直是以BranFactory接口以及它的默认实现类XMLBeanFactory为例进行分析,但是spring还提供了一个接口ApplicationContext,用于扩展BeanFactory现有的功能。我们先来看下类图

今天主要分析的是如何通过ApplicationContext来加载整个bean的流程。相信很多人都知道,是通过refresh()方法来开始加载加载整个bean的流程的,那我们来看这个方法,

它是位于spring-context模块下org.springframework.context.support目录下面。

再来看这个方法做了什么?我先贴上一段代码,附上一些简洁的注释,下面我们再重点讲一下里面的几个方法。

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			// 准备刷新上下文的环境,例如对系统属性及环境变量的初始化及验证
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 初始化BeanFactory,并进行XML的读取;经过此函数后,ApplicationContext就已经拥有了BeanFactory的全部功能。
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 对BeanFactory进行各种功能的填充
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 允许子类做额外的处理
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 激活BeanFactory处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 注册拦截Bean创建的Bean处理器,这里只是注册,真正调用的时候是在getBean的时候
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 为上下文初始化Message源,即不同语言的消息体,国际化处理
				initMessageSource();

				// Initialize event multicaster for this context.
				// 初始化应用消息广播器,并放入'applicationEventMulticaster' bean中
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 留给子类来初始化其他的Bean
				onRefresh();

				// Check for listener beans and register them.
				// 在所有注册的bean中查找Listener bean,注册到消息广播器中
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 完成刷新过程,通知声明周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// 结束刷新的过程
				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;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

这段代码的风格绝对符合spring编码的规范,将每个步骤应该干的事情全部封装起来,让读者清晰的了解它整体的运行逻辑,来看第一个方法prepareRefresh(),

prepareRefresh()

这段代码就不附上具体的代码了,主要讲下具体的作用:主要就是做一些准备工作,例如容器状态设置、对系统属性及环境变量的初始化和验证,里面重点提2个方法

  • initPropertySources(),这个在AbstractApplicationContext中是一个空方法,没有任何逻辑,主要是给用户最大扩展Spring的能力。用户可以根据自身的需要重写 initPropertySources 方法,并在方法中进行个性化的属性处理及设置。
  • validateRequiredProperties(),是对属性进行验证。举个例子,代码在启动的时候需要依赖系统环境变量中的一些配置,而如果用户在系统变量中没有这个配置,那个代码就会抛异常。

obtainFreshBeanFactory()

这个方法的主要作用就是获取初始化BeanFactory,也就是获取Bean工厂

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//初始化BeanFactory,并进行XML文件读取,并将得到的BeanFacotry记录在当前实体的属性中
		refreshBeanFactory();
		// 返回当前beanFactory的属性
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

这里面重要的方法是refreshBeanFactory(),这个方法的主要最用就是创建DefaultListableBeanFactory,并设置序列化id,然后通过loadBeanDefinitions去解析出BeanDefinition,再使用全局的DefaultListableBeanFactory记录结果

protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			// 创建DefaultListableBeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			// 为了序列化指定id,如果需要的话,让这个BeanFactory从id反序列化到BeanFactory对象
			beanFactory.setSerializationId(getId());
			// 定制BeanFactory,设置相关属性,包括是否允许覆盖同名称下的不同定义的对象以及循环依赖以及
			// 设置@Autowired 和 @Qualifier 注解解析器 QualifierAnnotationAutowireCandidateResolver
			customizeBeanFactory(beanFactory);
			// 初始化DocumentReader,并进行XML文件的读取以及解析
			loadBeanDefinitions(beanFactory);
			this.beanFactory = beanFactory;
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

总结一下就是:

  1. 创建DefaultListableBeanFactory。在介绍BeanFactory的时候,声明方式为:BeanFactory bf = new XmlBeanFactory("beanFactoryTest.xml"),其中的XmlBeanFactory继承自DefaultListableBean Factory,并提供了XmlBeanDefinitionReader类型的reader属性,也就是说DefaultListableBeanFactory是容器的基础。必须首先要实例化,那么在这里就是实例化。
  2. 指定序列化ID

  3. 定制BeanFactory。

  4. 加载BeanDefinition。

  5. 使用全局变量记录BeanFactory类实例。

因为DefaultListableBeanFactory类型的变量beanFactory是函数内的局部变量,所以要使用全局变量记录解析结果。

prepareBeanFactory()

进入函数prepareBeanFactory前,Spring已经完成了对配置的解析,而ApplicationContext在功能上的扩展也由此展开。这段代码比较长,但是里面的功能逻辑非常清晰,我们来看一下

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		//设置beanFactory的classLoader为当前context的classLoader
		beanFactory.setBeanClassLoader(getClassLoader());
		//设置beanFactory的表达式语言处理器,Spring3增加了表达式语言的支持,
		//默认可以使用#{bean.xxx}的形式来调用相关属性值。
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//为beanFactory增加了一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		// 添加BeanPostProcessor
		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.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		//增加对AspectJ的支持
		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.
		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());
		}
	}

看上面的注解其实也能大概明白其中的具体作用,我们也不必深入去了解,大致总结一下这块做的事情

  1. 增加对SPEL语言的支持。
  2. 增加对属性编辑器的支持。
  3. 增加对一些内置类,比如EnvironmentAware、MessageSourceAware的信息注入。
  4. 设置了依赖功能可忽略的接口。
  5. 注册一些固定依赖的属性。
  6. 增加AspectJ的支持(通过增加一些组件来实现)。
  7. 将相关环境变量及属性注册以单例模式注册。

postProcessBeanFactory()

这个方法正如我们最开始在注释中写的那样,主要是为了给子类中重写以便子类在BeanFactory创建完成后做进一步的操作,它本身是一个空的方法。

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	}

invokeBeanFactoryPostProcessors()

这个方法主要作用是调用BeanFactoryPostProcessors来处理一些定义bean的后置操作

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()));
		}
	}

首先我们先来看 getBeanFactoryPostProcessors()这个方法是如何获取到BeanFactoryProcessors的:对于硬编码注册的后处理器的处理,主要是通过AbstractApplicationContext中的添加处理器方法addBeanFactoryPostProcessor进行添加。ps:系统监听器启动的时候会添加BeanFactoryPostProcessor和配置文件加载玩后也会注添加一些BeanFactoryPostProcessor

public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
		Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
		this.beanFactoryPostProcessors.add(postProcessor);
	}
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
		return this.beanFactoryPostProcessors;
	}

再来看最关键的方法:invokeBeanFactoryPostProcessors()这个方法很长,有180多行,这里就不全部展示,我们先来看一部分,再分析其具体的作用

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    Set<String> processedBeans = new HashSet<>();
		//对BeanDefinitionRegistry类型的处理
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					//对于BeanDefinitionRegistryPostProcessor类型,在BeanFactoryPostProcessor的基础上还有自己定义的方法,需要先调用
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					//记录常规BeanFactoryPostProcessor
					regularPostProcessors.add(postProcessor);
				}
			}
        ...
        }
        else{
            ...    
        }
        ...
}

registryPostProcessors:记录通过硬编码方式注册的BeanDefinitionRegistryPostProcessor类型的处理器。

regularPostProcessors:记录常规BeanFactoryPostProcessor类型的处理器。

processedBeans:记录通过硬编码方式注册的BeanDefinitionRegistryPostProcessor类型的处理器。

registryProcessors:记录通过配置方式注册的BeanDefinitionRegistryPostProcessor类型的处理器。

这个记住这几个集合的作用。 再来看

List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        processedBeans.add(ppName);
    }
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanDefinitionRegistry(registry);
		}
	}

上面这两段代码的意思是:

  1. 遍历bean,获取BeanDefinitionRegistryPostProcessor类型的bean,
  2. 如果有实现PriorityOrdered接口,就加入到currentRegistryProcessors列表中和processedBeans集合中
  3. 对currentRegistryProcessors处理器进行分类
  4. 加入到registryProcessors
  5. 循环currentRegistryProcessors列表,调用元素的postProcessBeanDefinitionRegistry方法
  6. 清除currentRegistryProcessors缓存

看源码我们会发现,接下来的好几个代码块全部都是和这部分代码一致,下面就是,如果有实现Ordered.class接口,则会安装上面的方式重新来一遍过程。再下面都是一些重复的过程,为什么要重复呢,因为spring要判断所有的BeanFactoryProcessors,每次重复都是内部判断条件不一致,避免遗漏。

用几张图来总结一下invokeBeanFactoryPostProcessors()方法:

这四张图基本说明了invokeBeanFactoryPostProcessors()方法的作用,主要就是避免遗漏对实现了BeanDefinitionRegistryPostProcessor接口的类的处理。到这里我们invokeBeanFactoryPostProcessors()方法就讲完了。

registerBeanPostProcessors();

现在我们来探索下BeanPostProcessor,但是这里并不是调用,而是注册。真正的调用其实是在 bean 的实例化阶段进行的。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
registerBeanPostProcessors这个方法很长,这里我们不粘贴代码过来了,这个方法的主要作用为:
  1. 找到BeanPostProcessor的实现
  2. 排序后注册进容器

按照源码的步骤具体来看下:

//第一步,注册所有实现PriorityOrdered的BeanPostProcessor
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		//第二步,注册所有实现Ordered的BeanPostProcessor
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		//第三步,注册所有无序的BeanPostProcessor
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		//第四步,注册所有MergedBeanDefinitionPostProcessor类型的BeanPostProcessor,并非重复注册,
		//在beanFactory.addBeanPostProcessor中会先移除已经存在的BeanPostProcessor
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		//添加ApplicationListener探测器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

首先我们会发现,对于 BeanPostProcessor 的处理与 BeanFactoryPostProcessor 的处理极为相似,但是似乎又有些不一样的地方。经过反复的对比发现,对于 BeanFactoryPostProcessor的处理要区分两种情况,一种方式是通过硬编码方式的处理,另一种是通过配置文件方式的处理

对于 BeanFactoryPostProcessor的处理,不但要实现注册功能,而且还要实现对后处理器的激活操作,所以需要载入配置中的定义,并进行激活;而对于BeanPostProcessor并不需要马上调用,再说,硬编码的方式实现的功能是将后处理器提取并调用,这里并不需要调用,当然不需要考虑硬编码的方式了,这里的功能只需要将配置文件的BeanPostProcessor提取出来并注册进入beanFactory就可以了。

对于 BeanFactoryPostProcessor的处理,不但要实现注册功能,而且还要实现对后处理器的激活操作,所以需要载入配置中的定义,并进行激活;而对于BeanPostProcessor并不需要马上调用,再说,硬编码的方式实现的功能是将后处理器提取并调用,这里并不需要调用,当然不需要考虑硬编码的方式了,这里的功能只需要将配置文件的BeanPostProcessor提取出来并注册进入beanFactory就可以了。

对于 beanFactory 的注册,也不是直接注册就可以的。在 Spring 中支持对于 BeanPost Processor的排序,比如根据PriorityOrdered进行排序、根据Ordered进行排序或者无序,而Spring在BeanPostProcessor的激活顺序的时候也会考虑对于顺序的问题而先进行排序。

initMessageSource()

初始化国际化相关的属性,会先判断bean工厂是否包含国际化的BeanName,没有的话就会创建一个

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.isDebugEnabled()) {
				logger.debug("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.isDebugEnabled()) {
				logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
						"': using default [" + this.messageSource + "]");
			}
		}
	}

initApplicationEventMulticaster()

初始化事件广播器,注册到容器当中,逻辑很简单,spring的事件监听的用法就不再描述,不清楚的同学可以去看下 ApplicationEvent和ApplicationListener的简单实现

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.isDebugEnabled()) {
				logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
						APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
						"': using default [" + this.applicationEventMulticaster + "]");
			}
		}
	}

当产生 Spring 事件的时候会默认使用 SimpleApplicationEventMulticaster 的multicastEvent来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent方法来进行监听器的处理。而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则由事件监听器来决定。

onRefresh()

这个方法也是一个空实现,和之前讲的initPropertySources()方法一样,是留给子类实现的,此处是的作用是留给子类来初始化其他的Bean;对于web容器内的实现是createWebServer,如tomcat。

registerListeners()

注册监听器:1.添加容器内的监听事件器至事件广播器中,2.广播早期注册到applicationEventMulticaster的事件

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!
		// 配置文件注册的监听器处理
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			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);
			}
		}
	}

finishBeanFactoryInitialization()

完成BeanFactory的初始化工作,其中包括ConversionService的设置、配置冻结以及非延迟加载的bean的初始化工作。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		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));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		// 冻结所有的bean定义,说明注册的bean的定义将不被修改或者任何进一步的处理
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 初始化剩下的单实例(非惰性的)
		beanFactory.preInstantiateSingletons();
	}

总结一下:

  1. ConversionService的设置:之前我们提到过使用自定义类型转换器从String转换为Date的方式,那么,在Spring中还提供了另一种转换方式:使用Converter,具体例子就不再详述了
  2. 冻结配置:冻结所有的bean定义,说明注册的bean定义将不被修改或进行任何进一步的处理。
  3. 初始化非延迟加载:ApplicationContext 实现的默认行为就是在启动时将所有单例 bean 提前进行实例化。提前实例化意味着作为初始化过程的一部分,ApplicationContext实例会创建并配置所有的单例bean。通常情况下这是一件好事,因为这样在配置中的任何错误就会即刻被发现(否则的话可能要花几个小时甚至几天)。而这个实例化的过程就是在 finishBeanFactoryInitialization 中完成的。

finishRefresh()

protected void finishRefresh() {
		// Clear context-level resource caches (such as ASM metadata from scanning).
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}

1.initLifecycleProcessor
当ApplicationContext启动或停止时,它会通过LifecycleProcessor来与所有声明的bean的周期做状态更新,而在LifecycleProcessor的使用前首先需要初始化。

2.onRefresh
启动所有实现了Lifecycle接口的bean。

3.publishEvent
当完成ApplicationContext初始化的时候,要通过Spring中的事件发布机制来发出Context RefreshedEvent事件,以保证对应的监听器可以做进一步的逻辑处理。

 

至此,ApplicationContext启动代码分析结束,如果你能看到这,请给自己鼓个掌,感谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周润发的弟弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值