Spring IOC容器启动流程refresh()方法源码分析

前言

refresh()方法所有的ApplicationContext子类都没重写,只有AbstractApplicationContext里有实现过(接口定义在ConfigurableApplicationContext),因此我们看起来也容易了,直接上源码~

public void refresh() throws BeansException, IllegalStateException {
    //“刷新”和“销毁”的同步监视器
	synchronized (this.startupShutdownMonitor) {
		// 容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等
		prepareRefresh();

		// 获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等  注意,此处是获取新的,销毁旧的,这就是刷新的意义
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// 配置beanFactory的标准上下文特征
		prepareBeanFactory(beanFactory);

		try {
				//因为beanFactory都准备好了,子类可以自己去实现自己的逻辑。
				//比如一些web的ApplicationContext,就实现了自己的逻辑,做一些自己的web相关的事情
				postProcessBeanFactory(beanFactory);

				// 实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean)。
				//在beanFactory标准初始化之后执行  例如:PropertyPlaceholderConfigurer(处理占位符)
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
				//例如:
				//AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
				//RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
				//CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。
				registerBeanPostProcessors(beanFactory);

				//初始化国际化工具类MessageSource
				initMessageSource();

				//初始化事件广播器
				initApplicationEventMulticaster();

				//模板方法,在容器刷新的时候可以自定义逻辑(子类自己去实现逻辑),不同的Spring容器做不同的事情
				onRefresh();

				//注册监听器,并且广播early application events,也就是早期的事件
				registerListeners();

				//非常重要。。。实例化所有剩余的(非懒加载)单例Bean。(也就是我们自己定义的那些Bean们)
				//比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化  扫描的 @Bean之类的
				//实例化的过程各种BeanPostProcessor开始起作用~~~~~~~~~~~~~~
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				//refresh做完之后需要做的其他事情
				//清除上下文资源缓存(如扫描中的ASM元数据)
				//初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
				//发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
				finishRefresh();
			}

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

				//如果刷新失败那么就会将已经创建好的单例Bean销毁掉
				destroyBeans();

				//重置context的活动状态 告知是失败的
				cancelRefresh(ex);

				//抛出异常
				throw ex;
			}

			finally {
				// 失败与否,都会重置Spring内核的缓存。因为可能不再需要metadata给单例Bean了。
				resetCommonCaches();
			}
		}
	}

通过上面的注释,已经能够比较宏观的了解到容器的一个初始化过程了,那么接下来,将针对每一个步骤,进行微观源码级别的解释说明。

第一步:容器刷新前的准备工作

  • prepareRefresh()
protected void prepareRefresh() {
		//记录容器启动时间,然后设立对应的标志位
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		// 打印info日志:开始刷新this此容器了
		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// 这是扩展方法,由AbstractApplicationContext的子类去实现,可以在验证之前为系统属性设置一些值可以在子类中实现此方法
		initPropertySources();

		//这里有两步,getEnvironment(),然后是是验证是否系统环境中有RequiredProperties参数值 如下详情
		// 然后管理Environment#validateRequiredProperties 后面在讲到环境的时候再专门讲解吧
		// 这里其实就干了一件事,验证是否存在需要的属性
		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<>();
	}

第二步:重新创建一个bean工厂

  • ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}
protected final void refreshBeanFactory() throws BeansException {
		// 判断是否已经存在BeanFactory,存在则销毁所有Beans,并且关闭BeanFactory
		// 避免重复加载BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			// 创建具体的beanFactory,这里创建的是DefaultListableBeanFactory,最重要的beanFactory spring注册及加载bean就靠它
			// createBeanFactory()这个方法,看下面,还有得说的
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			// 这句比较简单,就是把当前旧容器的一些配置值复制给新容器
			// allowBeanDefinitionOverriding属性是指是否允对一个名字相同但definition不同进行重新注册,默认是true。
			// allowCircularReferences属性是指是否允许Bean之间循环引用,默认是true.
			// 这两个属性值初始值为空:复写此方法即可customizeBeanFactory
			customizeBeanFactory(beanFactory);
			// 这个就是最重要的了,加载所有的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);
		}
	}

这段代码中有2个重要步骤

第一段代码

DefaultListableBeanFactory beanFactory = createBeanFactory();
// 创建的时候就是new了一个工厂:DefaultListableBeanFactory   这个时候工厂里面所有东西都是默认值,很多还没有完成初始化属性的设置呢
	protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}
	
	// 给设置父的BeanFactory,若存在的话
	public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
		this();
		setParentBeanFactory(parentBeanFactory);
	}

	// 父类空构造器有这么些语句
	public AbstractAutowireCapableBeanFactory() {
		super();
		
		// 这里是重点。忽略自动装配。这里指定的都是接口。什么意思呢?
		// ignoreDependencyInterface的真正意思是在自动装配时忽略指定接口的实现类中,对外的依赖。(这里面注意:@Autowired和它的关系,其实是有坑的,后续会专门讲解这个坑)
		ignoreDependencyInterface(BeanNameAware.class);
		ignoreDependencyInterface(BeanFactoryAware.class);
		ignoreDependencyInterface(BeanClassLoaderAware.class);
	}
	
	//找到父的,若存在就返回 若存在父容器就存在父的BeanFactory
	@Nullable
	protected BeanFactory getInternalParentBeanFactory() {
		return (getParent() instanceof ConfigurableApplicationContext) ?
				((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
	}

第二段代码

loadBeanDefinitions(beanFactory);

它属于模版方法,加载所有的Bean配置信息,由子类去实现加载的方式,具体如下详细解释:

在这里以AnnotationConfigWebApplicationContext#loadBeanDefinitions()方法为例子

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
		// 初始化这个脚手架 其实就是直接new出实例。具体做的工作,下面有相关博文链接
		AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory);
		ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory);

		// 生成Bean的名称的生成器,如果自己没有setBeanNameGenerator(可以自定义),这里目前为null
		BeanNameGenerator beanNameGenerator = getBeanNameGenerator();
		if (beanNameGenerator != null) {
			reader.setBeanNameGenerator(beanNameGenerator);
			scanner.setBeanNameGenerator(beanNameGenerator);
			//若我们注册了beanName生成器,那么就会注册进容器里面
			beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
		}
		
		//这是给reader和scanner注册scope的解析器  此处为null
		ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver();
		if (scopeMetadataResolver != null) {
			reader.setScopeMetadataResolver(scopeMetadataResolver);
			scanner.setScopeMetadataResolver(scopeMetadataResolver);
		}

		// 此处注意了:annotatedClasses和basePackages一般是选其一(当然看到此处,他们是可以并存的)
		//我们可以自己指定annotatedClasses 配置文件,同时也可以交给下面扫描
		if (!this.annotatedClasses.isEmpty()) {
			
			// 这里会把所有的配置文件输出=======info日志  请注意观察控制台
			if (logger.isInfoEnabled()) {
				logger.info("Registering annotated classes: [" +
						StringUtils.collectionToCommaDelimitedString(this.annotatedClasses) + "]");
			}
			
			// 若是指明的Bean,就交给reader去处理,至于怎么处理,见上篇博文的doRegisterBean去怎么解析每一个Config Bean的
			reader.register(ClassUtils.toClassArray(this.annotatedClasses));
		}
		
		// 也可以是包扫描的方式,扫描配置文件的Bean
		if (!this.basePackages.isEmpty()) {
			// 输出对应的info日志
			if (logger.isInfoEnabled()) {
				logger.info("Scanning base packages: [" +
						StringUtils.collectionToCommaDelimitedString(this.basePackages) + "]");
			}
			
			// 这里重要了,scan方法具体做了什么事,上篇博文也有详细的介绍,请参阅
			scanner.scan(StringUtils.toStringArray(this.basePackages));
		}
		
		// 此处的意思是,也可以以全类名的形式注册。比如可以调用setConfigLocations设置(这在xml配置中使用较多)  可以是全类名,也可以是包路径
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			for (String configLocation : configLocations) {
				try {
					Class<?> clazz = ClassUtils.forName(configLocation, getClassLoader());
					reader.register(clazz);
				} catch (ClassNotFoundException ex) {
					// 发现不是全类名,那就当作包扫描吧
					int count = scanner.scan(configLocation);
				}
			}
		}
	}

最开始涉及到两个类的初始化,请参考博文:
【小家Spring】Spring容器加载Bean定义信息的两员大将:AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner

有了这篇博文解释这两个类先行,理解上面loadBeanDefinitions就简单太多了。至此,整个ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();这个步骤全部结束。
现在BeanFactory已经创建了,并且Config配置文件的Bean定义已经注册完成了**(备注:其它单例Bean是还没有解析的~~~~)**
显然,下面的步骤大都把BeanFactory传进去了,都是基于此Bean工厂的了~~~

第三步:配置工厂的标准上下文特征

  • prepareBeanFactory(beanFactory)
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 设置beanFactory的classLoader为当前context的classLoader
		beanFactory.setBeanClassLoader(getClassLoader());
		// 设置EL表达式解析器(Bean初始化完成后填充属性时会用到)
		// spring3增加了表达式语言的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		//设置属性注册解析器PropertyEditor 这个主要是对bean的属性等设置管理的一个工具
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// 将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理,从而在Aware接口实现类中的注入applicationContext等等
		// 添加了一个处理aware相关接口的beanPostProcessor扩展,主要是使用beanPostProcessor的postProcessBeforeInitialization()前置处理方法实现aware相关接口的功能
		// 类似的还有ResourceLoaderAware、ServletContextAware等等等等
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		// 下面是忽略的自动装配(也就是实现了这些接口的Bean,不要Autowired自动装配了)
		// 默认只有BeanFactoryAware被忽略,所以其它的需要自行设置
		// 因为ApplicationContextAwareProcessor把这5个接口的实现工作做了(具体你可参见源码) 所以这里就直接忽略掉
		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的类,就注册beanFactory
		//  如果是ResourceLoader、ApplicationEventPublisher、ApplicationContext等等就注入当前对象this(applicationContext对象)

		// 此处registerResolvableDependency()方法注意:它会把他们加入到DefaultListableBeanFactory的resolvableDependencies字段里面缓存这,供后面处理依赖注入的时候使用 DefaultListableBeanFactory#resolveDependency处理依赖关系
		// 这也是为什么我们可以通过依赖注入的方式,直接注入这几个对象比如ApplicationContext可以直接依赖注入
		// 但是需要注意的是:这些Bean,Spring的IOC容器里其实是没有的。beanFactory.getBeanDefinitionNames()和beanFactory.getSingletonNames()都是找不到他们的,所以特别需要理解这一点
		// 至于容器中没有,但是我们还是可以@Autowired直接注入的有哪些,请看下图:
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// 注册这个Bean的后置处理器:在Bean初始化后检查是否实现了ApplicationListener接口
		// 是则加入当前的applicationContext的applicationListeners列表 这样后面广播事件也就方便了
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// 检查容器中是否包含名称为loadTimeWeaver的bean,实际上是增加Aspectj的支持
		// AspectJ采用编译期织入、类加载期织入两种方式进行切面的织入
		// 类加载期织入简称为LTW(Load Time Weaving),通过特殊的类加载器来代理JVM默认的类加载器实现
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			// 添加BEAN后置处理器:LoadTimeWeaverAwareProcessor
			// 在BEAN初始化之前检查BEAN是否实现了LoadTimeWeaverAware接口,
			// 如果是,则进行加载时织入,即静态代理。
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 注入一些其它信息的bean,比如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());
		}
	}

第四步:模版方法

  • postProcessBeanFactory(beanFactory)

这是一个模版方法。因为beanFactory都准备好了,子类可以自己去实现自己的逻辑。

在这里我们以AbstractRefreshableWebApplicationContext的postProcessBeanFactory方法为例子

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		//注册ServletContextAwareProcessor 这样任意Bean都可以很方便的获取到ServletContext了  
		//同时忽略另外两个,因为ServletContextAwareProcessor 都把事情都做了
		beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
		beanFactory.ignoreDependencyInterface(ServletContextAware.class);
		beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

		//注册web环境,包括request、session、golableSession、application
		WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
		//注册servletContext、contextParamters、contextAttributes  、servletConfig单例bean
		WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
	}

第五步:执行BeanFactory后置处理器

  • invokeBeanFactoryPostProcessors

实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean)

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

		//这里就是定制:如果loadTimeWeaver这个Bean存在,那么就会配置上运行时织入的处理器LoadTimeWeaverAwareProcessor
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

这里面我们必须先看看getBeanFactoryPostProcessors()这个方法

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
	return this.beanFactoryPostProcessors;
}

这里非常有意思。方法非常简单,但有意思在于:它不是返回Spring容器里面的Processors,而是你自己的注册的(你自己手动set的),也就是说我们自己手动调用set方法添加进去,就能够执行。并不需要自己配置@Bean或者在xml里配置

那么执行beanFactory后置处理器的重点就在于这段代码

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		
		// 这个doc说明很清楚:不管怎么样,先执行BeanDefinitionRegistryPostProcessors
		// 需要注意的是BeanDefinitionRegistryPostProcessors 为 BeanFactoryPostProcessor 的子接口 它新增了方法:void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
		// BeanFactoryPostProcessor 的方法为;void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
		// 所以BeanDefinitionRegistryPostProcessors,它可以我们介入,改变Bean的一些定义信息
		Set<String> processedBeans = new HashSet<>();

		//只有此beanFactory 是BeanDefinitionRegistry  才能执行BeanDefinitionRegistryPostProcessor,才能修改Bean的定义嘛~
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			//装载普通的BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			//装载和Bean定义有关的 BeanDefinitionRegistryPostProcessor
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			// 从此处可以看出,我们手动set进去的,最先限执行的
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
					// 这里执行post方法,然后然后吧它缓冲起来了,放在了registryProcessors里
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					// 缓冲起来常规的处理器
					regularPostProcessors.add(postProcessor);
				}
			}

			
			// 接下来,就是去执行Spring容器里面的一些PostProcessor了。他们顺序doc里也写得很清楚:
			// 先执行实现了PriorityOrdered接口的,然后是Ordered接口的,最后执行剩下的
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			// 先从容器中拿出来所有的BeanDefinitionRegistryPostProcessor 然后先执行PriorityOrdered
			// 本例中有一个这个类型的处理器:ConfigurationClassPostProcessor(显然是处理@Configuration这种Bean的)
			// 至于这个Bean是什么时候注册进去的,前面有。在loadBeanDefinitions()初始化AnnotatedBeanDefinitionReader的时候调用的AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)方法的时候,注册了6个Bean
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					// processedBeans也顺带保存了一份,保存的是bean的Name哦~
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			// 排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 此处缓冲起来(需要注意的是,是排序后,再放进去的 这样是最好的)
			registryProcessors.addAll(currentRegistryProcessors);
			// 这个方法很简单,就是吧currentRegistryProcessors里面所有的处理器for循环一个个的执行掉
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			// 此处把当前持有的执行对象给清空了,需要注意。以方便装载后续执行的处理器们
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			// 此处逻辑完全同上  处理实现Order接口的RegistryProcessors
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			// 最后执行,两个排序接口都没有实现的BeanDefinitionRegistryPostProcessor们,并且也缓存起来
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			// 现在,这里很明显:去执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
			// 以及 顶层接口BeanFactoryPostProcessor的postProcessBeanFactory方法
			// 我们当前环境regularPostProcessors长度为0.registryProcessors有一个解析@Configuration的处理器
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			// 若是普通的Bean工厂,就直接执行set进来的后置处理器即可(因为容器里就没有其它Bean定义了)
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		// 下面就是开始执行BeanFactoryPostProcessor 基本也是按照上面的顺序来执行的
		// 上面9个Bean,我们知道 也就ConfigurationClassPostProcessor是实现了此接口的。因此本环境下,只有它了,并且它在上面还已经执行了
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}

第六步:实例化和注册扩展了BeanPostProcessor的bean

  • registerBeanPostProcessors(beanFactory)
  • 这一步:我们从所有的@Bean定义中抽取出来了BeanPostProcessor然后都注册进去,等待后面的的顺序调用
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		// 从所与Bean定义中提取出BeanPostProcessor类型的Bean,显然,最初的6个bean,有三个是BeanPostProcessor:
		// AutowiredAnnotationBeanPostProcessor  RequiredAnnotationBeanPostProcessor  CommonAnnotationBeanPostProcessor
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		//存放PriorityOrdered类型的后置处理器
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		//存放同时是PriorityOrdered和MergedBeanDefinitionPostProcessor类型的后置处理器
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		//存放当前后置处理器是Ordered类型但不是PriorityOrdered类型的名字。
		List<String> orderedPostProcessorNames = new ArrayList<>();
		////存放当前后置处理器不是Ordered类型的名字。
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
		     //如果当前后置处理器是PriorityOrdered类型
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			//如果当前后置处理器是Ordered类型
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 首先,注册实现PriorityOrdered的BeanPostProcessors。
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 接下来,注册实现Ordered接口,但是没有实现PriorityOrdered接口的BeanPostProcessors。
		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);

		// 现在,注册非Ordered类型的后置处理器
		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);

		// 最后,重新注册所有内部beanpstprocessors。
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		//重新注册后处理器,以便将内部bean检测为应用程序侦听器,
        //将其移动到处理器链的末端(用于获取代理等)。
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

第七步:初始化消息源

  • initMessageSource()

若用户自己定义了这个名为messageSourceMessageSource类型Bean,就以用户的为准。
否则注册一个系统默认的消息源DelegatingMessageSource,其名字是messageSource

protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		// 判断是否已经存在名为“messageSource”的Bean了(一般情况下,我们都是没有的)
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			// 注册messageSource,并从容器里拿出这个messageSource
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// 设置父属性。
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					//仅当没有父消息源时才将父上下文设置为父消息源
                    hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
			//使用空的MessageSource可以接受getMessage调用。
			DelegatingMessageSource dms = new DelegatingMessageSource();
			// 其实就是获取到父容器的messageSource字段(否则就是getParent()上下文自己)
			dms.setParentMessageSource(getInternalParentMessageSource());
			// 给当前的messageSource赋值
			this.messageSource = dms;
			// 把messageSource作为一个单例的Bean注册进beanFactory工厂里面
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
			}
		}
	}

第八步:初始化事件广播器

  • initApplicationEventMulticaster()

若用户自己定义了这个名为applicationEventMulticasterApplicationEventMulticaster类型Bean,就以用户的为准。
否则注册一个系统默认的事件广播器SimpleApplicationEventMulticaster,其名字是applicationEventMulticaster

protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//如果容器中包含applicationEventMulticaster
		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 + "]");
			}
		}
		//如果容器中不包含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() + "]");
			}
		}
	}

第九步:模版方法

  • onRefresh()

模板方法,在容器刷新的时候可以自定义逻辑(子类自己去实现逻辑),不同的Spring容器做不同的事情
下面是AbstractRefreshableWebApplicationContext的onRefresh方法

protected void onRefresh() {
		this.themeSource = UiApplicationContextUtils.initThemeSource(this);
	}

第十步:注册监听器

  • registerListeners()
protected void registerListeners() {
		// 这一步和手动注册BeanDefinitionRegistryPostProcessor一样,可以自己通过set手动注册监听器  
		//然后是最先执行的(显然此处我们无自己set)
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			// 把手动注册的监听器绑定到广播器
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// 取到容器里面的所有的监听器的名称,绑定到广播器  后面会广播出去这些事件的
		// 同时提醒大伙注意:此处并没有说到ApplicationListenerDetector这个东东,下文会分解
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// 这一步需要注意了:如果存在早期应用事件,这里就直接发布了(同时就把earlyApplicationEvents该字段置为null)
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

第十一步:注册和初始化容器内所有的单例Bean

  • finishBeanFactoryInitialization(beanFactory)

第十二步:refresh做完之后需要做的其他事情

  • finishRefresh()

1、清除上下文资源缓存(如扫描中的ASM元数据)
2、初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
3、发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作

protected void finishRefresh() {
		// 表示清除一些resourceCaches,这个resourceCaches就是一个map,如doc说的  清楚context级别的资源缓存,比如ASM的元数据
		clearResourceCaches();

		// 初始化所有的LifecycleProcessor
		initLifecycleProcessor();

		// 上面注册好的处理器,这里就拿出来,调用它的onRefresh方法了
		getLifecycleProcessor().onRefresh();

		// 发布容器刷新的事件:
		publishEvent(new ContextRefreshedEvent(this));

		// 和MBeanServer和MBean有关的。相当于把当前容器上下文,注册到MBeanServer里面去。
		// 这样子,MBeanServer持久了容器的引用,就可以拿到容器的所有内容了,也就让Spring支持到了MBean的相关功能
		LiveBeansView.registerApplicationContext(this);
	}

初始化上下文的生命周期处理器

若用户自己定义了这个名为lifecycleProcessorLifecycleProcessor类型Bean,就以用户的为准。
否则注册一个系统默认的上下文的生命周期处理器DefaultLifecycleProcessor,其名字是LifecycleProcessor

protected void initLifecycleProcessor() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//如果容器中存在lifecycleProcessor
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
			//使用当前的bean
			this.lifecycleProcessor =
					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		}
		//如果容器中不存在lifecycleProcessor
		else {
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			defaultProcessor.setBeanFactory(beanFactory);
			this.lifecycleProcessor = defaultProcessor;
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
						"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
			}
		}
	}

通知上下文刷新

  • getLifecycleProcessor().onRefresh()
public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware{
@Override
	public void onRefresh() {
		startBeans(true);
		this.running = true;
	}
private void startBeans(boolean autoStartupOnly) {
		 //拿到所有的实现了Lifecycle/SmartLifecycle的  已经在IOC容器里面的单例Bean们(备注:不包括自己this,也就是说处理器自己不包含进去)
		// 这里若我们自己没有定义过实现Lifecycle的Bean,这里就是空的
		Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
		Map<Integer, LifecycleGroup> phases = new HashMap<>();
		lifecycleBeans.forEach((beanName, bean) -> {
			// 若Bean实现了SmartLifecycle 接口并且标注是AutoStartup  或者  强制要求自动自行的autoStartupOnly = true
			if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
				int phase = getPhase(bean);
				LifecycleGroup group = phases.get(phase);
				if (group == null) {
					group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
					phases.put(phase, group);
				}
				group.add(beanName, bean);
			}
		});
		if (!phases.isEmpty()) {
			List<Integer> keys = new ArrayList<>(phases.keySet());
			Collections.sort(keys);
			for (Integer key : keys) {
				phases.get(key).start();
			}
		}
	}

就这样,实现了Lifecycle接口的Bean start方法什么时候调用就有门路了。

从上面的源码中,我们能够读出什么异常的地方呢?我们发现Lifecycle这个接口并不能直接使用。
因为DefaultLifecycleProcessor的onRefresh方法传值为autoStartupOnly=true:表示只有实现了SmartLifecycle的Bean才会调用start方法,因为实现了SmartLifecycle接口会有一个phase值,根据上面源码会根据此值分组执行。
autoStartupOnly=false则只要是Lifecycle 的实现既可以被调用,我们会给其默认的phase。

所以,我们要想要这个功能,请实现SmartLifecycle,而不是Lifecycle接口

发布了34 篇原创文章 · 获赞 0 · 访问量 1367

猜你喜欢

转载自blog.csdn.net/qq_41071876/article/details/104585779