spring5源码篇(8)——容器的启动

spring-framework 版本:v5.3.19

refresh

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// 刷新前的一些准备工作
			// 设置spring上下文的一些状态
			prepareRefresh();

			// 获得beanFactory
			// 如果是注解方式,这一步没干什么,只setSerializationId。(beanFactory已经调用父类GenericApplicationContext构造方法的时候创建了)
			// 如果是xml方式,这一步会创建一个beanFactory并且loadBeanDefinitions
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 准备beanFactory(对一些属性赋值等操作)
			prepareBeanFactory(beanFactory);

			try {
				// 扩展方法,本身为空,子类覆盖做额外的处理(xml和注解都没有覆盖)
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// 执行beanFactoryPostProcessor
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册BeanPostProcessors
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// 初始化国际化处理中的Message源
				initMessageSource();

				// 初始化消息广播器
				initApplicationEventMulticaster();

				// 扩展方法,本身为空,子类覆盖做额外的处理(xml和注解都没有覆盖)
				onRefresh();

				// 注册Listener bean 到消息广播器中
				registerListeners();

				// 完成beanFactory初始化后的一些操作。其中最重要的就包括创建剩下的单例(非惰性)
				finishBeanFactoryInitialization(beanFactory);

				// 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
				finishRefresh();
			}

			catch (BeansException ex) {
				//......
			}

			finally {
				//......
			}
		}
	}

这里着重看以下几个方法

obtainFreshBeanFactory

在这里插入图片描述
可以发现xml配置下,beanFactory的创建和beanDefinition是在这一步完成的。那么注解方式的beanFactory的创建和beanDefinition加载又是如何完成的呢?
先说beanFactory的创建,因为AnnotationConfigApplicationContext继承自GenericApplicationContext。而GenericApplicationContext的无参构造中就已经创建beanFactory了。所以在构造AnnotationConfigApplicationContext是会先调用父类构造,从而创建beanFactory。
在这里插入图片描述
而至于注解bean的beanDefinition加载,这个其实早在第4篇的时候就已经分析过了。在后续的invokeBeanFactoryPostProcessors方法执行到ConfigurationClassPostProcessor这个beanFactoryPostProcessors的时候就会去解析配置类,加载配置类配置的beanDefinition。

invokeBeanFactoryPostProcessors

在这里插入图片描述
beanFactoryPostProcessors的执行会委托给PostProcessorRegistrationDelegate,执行invokeBeanFactoryPostProcessors方法。而这个方法在第4篇的时候也已经分析过了。在执行BeanFactoryPostProcessors方法时,保证先执行所有的BeanDefinitionRegistryPostProcessor(包括BeanDefinition中注册的)后再执行BeanFactoryPostProcessors(包括BeanDefinition中注册的),且两者的执行都按 spring本身已有的->BeanDefinition中PriorityOrdered修饰的->BeanDefinition中Ordered修饰的->BeanDefinition中其他未被执行的顺序执行

registerBeanPostProcessors

在这里插入图片描述
registerBeanPostProcessors的执行同样也委托给PostProcessorRegistrationDelegate。
registerBeanPostProcessors#PostProcessorRegistrationDelegate

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// 将实现priority、order和non优先级的beanPostProcessor分开。
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 第一步:注册实现priority的beanPostProcessor。
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 第二步:注册实现Ordered的beanPostProcessor。
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		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);

		// 第三步:注册所有常规的beanPostProcessor。
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// 第四步:注册所有MergedBeanDefinitionPostProcessor类型的BeanPostProcessor
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		//添加ApplicationContext探测器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

注册顺序:先注册beanPostProcessor,再注册MergedBeanDefinitionPostProcessor,且两者的注册都按 PriorityOrdered修饰的->Ordered修饰的->其他未被注册的顺序注册。

finishBeanFactoryInitialization

在这里插入图片描述
preInstantiateSingletons目前只有DefaultListableBeanFactory一个实现了。
DefaultListableBeanFactory#preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		//遍历所有beanDefinition
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//只先创建不是抽象,单例,非懒加载的bean
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					//FactoryBean情况 加 ‘&’ 前缀
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						// 如果实现了SmartFactoryBean且isEagerInit为true则提前实例化bean
						// 即同时会在factoryBeanObjectCache中添加beanName对应的使用实例(factoryBean接口返回的对象)
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					//非FactoryBean情况
					getBean(beanName);
				}
			}
		}

这里简单说一下factoryBean
假设有一个单例的factoryBean类CommonFactoryBean。那么最终spring会在signletonObjects和factoryBeanObjectCache都add一个key为commonFactoryBean的元素,signletonObjects存的就是CommonFactoryBean,而factoryBeanObjectCache存的就是factoryBean接口getObject方法的返回值。
当getBean传入的beanName是&commonFactoryBean时,就会返回factoryBean对应的实例。如果是commonFactoryBean则返回factoryBean接口getObject方法的返回值。

对于factoryBean的创建,一般情况下getBean(“&xxx”)会在单例池中add CommonFactoryBean,等以后需要用到的时候再去执行factoryBean接口的方法得到真正要使用的实例并添加到factoryBeanObjectCache中。但是如果这个factoryBean实现了SmartFactoryBean且isEagerInit为true则提前实例化bean,即立即执行getBean(“xxx”),此时发现得到的bean是一个factoryBean,然后就会执行factoryBean接口的方法得到真正要使用的实例,并将该实例添加到factoryBeanObjectCache中。

可以推断出getBean(“&xxx”)只会在单例池添加factoryBean实例,getBean(“xxx”)既会在单例池添加实例也会在factoryBeanObjectCache添加实例(与是否懒加载无关)。

总结

prepareRefresh
刷新前的准备工作,设置spring上下文的一些状态 |

obtainFreshBeanFactory
获得beanFactory。如果是注解方式,GenericApplicationContext重写了refreshBeanFactory方法只setSerializationId,beanFactory在之前调用父类GenericApplicationContext构造方法的时候创建了。如果是xml方式,这一步会创建一个beanFactory并且loadBeanDefinitions。

prepareBeanFactory
准备beanFactory,对一些属性赋值扩充容器功能。如增加一个默认的propertyEditor,添加BeanPostProcessor处理器(ApplicationContextAwareProcessor),设置几个忽略自动装配的接口,添加BeanPostProcessor处理器(ApplicationListenerDetector)等

postProcessBeanFactory
扩展接口

invokeBeanFactoryPostProcessors
执行beanFactoryPostProcessor

registerBeanPostProcessors
注册BeanPostProcessors

initMessageSource
初始化国际化处理中的Message源

initApplicationEventMulticaster
初始化消息广播器

onRefresh
扩展接口

registerListeners
注册Listener bean 到消息广播器中

finishBeanFactoryInitialization
完成beanFactory初始化后的一些操作。其中最重要的就包括创建剩下的单例(非惰性)

finishRefresh
完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人


最后结合前面的博文,总结到bean在各种时期的常见的增强有

  • refresh

    • invokeBeanFactoryPostProcessors
      • BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry ——容器启动时
      • BeanFactoryPostProcessor.postProcessBeanFactory ——容器启动时
  • registerBean

    • MergerBeanDefinitionPostProcess.resetBeanDefintion —— 注册bean时若对bean有重置则调用
  • createBean

    • InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation —— 实例化前
    • docreateBean
      • createBeanInstance

        • determineConstructorsFromBeanPostProcessors
          • SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors ——实例化时
      • MergerBeanDefinitionPostProcess.postprocessMergedBeanDefinition —— 实例化后

      • getEarlyBeanReference

        • SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference —— 循环依赖中暴露的早期对象
      • populateBean

        • InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation —— 实例化后
        • InstantiationAwareBeanPostProcessor.postProcessProperties ——填充属性后
      • initializeBean

        • invokeAwareMethods
          • beanNameAware,beanFactoryAware ,beanClassLoaderAware—— aware方法的执行
        • PostProcessors.postProcessBeforeInitialization —— 初始化前(其中ApplicationContextAwareProcessor会执行容器相关的ApplicationContenxtAware,ApplicationStartupAware等接口)
        • PostProcessors.postProcessAfterInstantiation —— 初始化后
      • registerDisposableBeanIfNecessary

        • DestructionAwareBeanPostProcessor.postProcessBeforeDestruction —— 销毁回调
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值