Spring系列(三) 从refresh看createBean源码解析

本文深入剖析了Spring框架中单例bean的创建过程,从启动代码开始,详细讲解了 AnnotationConfigApplicationContext 的构造、register步骤,重点解析了refresh方法中的invokeBeanFactoryPostProcessors、registerBeanPostProcessors和finishBeanFactoryInitialization等关键步骤,涉及BeanDefinition的注册、处理器的调用以及bean的实例化和初始化流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

createBean解析

spring当中单例bean的创建原理,其中涉及到了非常多阶段及各种处理器的调用

启动代码

通过注解配置类AppConfig启动一个容器,其中添加了一个自定义的beanFactoryPostProcessor, 注意:这个类是直接添加到beanFactoryPostProcessors中的,没有被spring当成bean放到单例map中

 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
        ac.addBeanFactoryPostProcessor(new CustomBeanFactoryPostProcessor());
        ac.register(AppConfig.class);
        ac.refresh();
new AnnotationConfigApplicationContext

完成的初始化:

this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);

初始化了AnnotatedBeanDefinitionReader又完成了spring内置几大处理器的注册

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

生成了对应RootBeanDefinition,并通过registry加到了map中

beanNamebeanClass
org.springframework.context.annotation.internalConfigurationAnnotationProcessorConfigurationClassPostProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessorAutowiredAnnotationBeanPostProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessorCommonAnnotationBeanPostProcessor
org.springframework.context.event.internalEventListenerProcessorEventListenerMethodProcessor
org.springframework.context.event.internalEventListenerFactoryDefaultEventListenerFactory
register 注册了自己的配置类

通过构造ApplicationContext时产生的reader解读这个注解类,并把配置类当成一个AnnotatedGenericBeanDefinition放入map中等待后续实例化。中间处理了一些common的注解信息并填冲到bd里,比如@Lazy,@Primary,@Role,@DependsOn, @Description等

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
refresh 方法解析

refresh方法中是个模板方法,里面定义了很多阶段操作,其中主要分析以下几个

invokeBeanFactoryPostProcessors(beanFactory)

主要完成了下面一个操作,其中getBeanFactoryPostProcessors()拿的就是我们手动add进去的那个processor列表,因此目前只有一个

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

第一步:优先遍历这个list,并加入到对应列表中

BeanDefinitionRegistryPostProcessor -> List<BeanDefinitionRegistryPostProcessor> registryProcessors
BeanFactoryPostProcessor -> List<BeanFactoryPostProcessor> regularPostProcessors

注意 这里对BeanDefinitionRegistryPostProcessor 会先触发 postProcessBeanDefinitionRegistry 因为可能在这个方法里面需要引入额外的banFactoryPostProcessor类,等待下一步执行

接下来开始按优先级顺序查找并执行beanFactory中目前的registryPostProcessor
此刻bd map中已经有了如下几个内置类:5个内置+1个自己注解类
在这里插入图片描述
第二步:从beanFactory中拿出所有PriorityOrdered BeanDefinitionRegistryPostProcessor的beanName
此时满足条件的只有 ConfigurationClassPostProcessor, beanFactory.getBean会将它产生出来并放到缓存中
在这里插入图片描述
并执行 处理器对registry的实现逻辑,这里的配置处理器会将目前所有的bd拿出来判断解析,构造所有需要产生的bd并存放起来 (执行了 )

for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanDefinitionRegistry(registry);
		}
step -> ConfigurationClassPostProcessor
      processConfigBeanDefinitions

判断beanDefinition中属性org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass是否有值(不成立,当前还没被设置过值)
然后checkConfigurationClassCandidate(看是不是候选的配置类)

  • 如果是配置类,产生的bd是AnnotatedGenericBean,会满足第一个条件设置好metaData
  • 如果这个bean是自己注册的,有可能是AbstractBeanDefinition类型,那么再看是不是BeanFactoryPostProcessor,BeanPostProcessor,AopInfrastructureBean,EventListenerFactory等特殊类型,不是的化也设置metadata否则直接结束

拿出Configuration注解的属性信息,允许代理bean方法情况下,设置注解属性为full(就是这个时候才添加了标记,对应前面第一次拿是空);如果没有@Configuration,拿出來的config是null,但是当前有@Bean method,else if中标记为lite
在这里插入图片描述
然后用ConfigurationClassParser 去解析配置类的相关信息,包括Component, PropertySources,ComponentScans,ComponentScan, @Import, ImportResource,
等,最终存在ConfigurationClass包装类中

    private final Set<ConfigurationClass> importedBy = new LinkedHashSet<>(1);
	private final Set<BeanMethod> beanMethods = new LinkedHashSet<>();
	private final Map<String, Class<? extends BeanDefinitionReader>> importedResources =
			new LinkedHashMap<>();
	private final Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars =
			new LinkedHashMap<>();
	final Set<String> skippedBeanMethods = new HashSet<>();

接着ConfigurationClassBeanDefinitionReader 去加载这些信息loadBeanDefinitions到bd map中
再通过registry直接往容器中的singletonObjects中注册一个处理Import注解的处理类 ,没有走beanDefinition->create逻辑

beanNamebeanClass
org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistryorg.springframework.context.annotation.ConfigurationClassParser.ImportStack

完成所有import和其他相关注解信息的处理后,相关需要被扫面加载的bd都已经被存放到beanFactory中的bd map中等待被创建了

第三步 再从容器中找出所有beanFactoryPostProcessor (还是只有一个被执行过的configuration处理类)
如果未被执行过或不是Order优先级的,跳过

第四步 从容器中找出所有beanFactoryPostProcessor,不对接口限制
处理所有未处理的process方法,并继续循环获取防止当前又产生新的处理器

第五步 对所有后置处理器(包括特殊的registry和普通beanFactoryPostprocessor)调用接口方法 postProcessBeanFactory

invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

ConfigurationClassPostProcessor postProcessBeanFactory
会对当前所有bd找出可能的注解类,只对full属性的类进行如下逻辑

  • CGLIB 增强@Configuration的类 , enhanceConfigurationClasses
    对标记为full的进行ConfigurationClassEnhancer enhance (保证@Bean method都为单例的,如果在方法调用中有多次)
  • 添加 ImportAwareBeanPostProcessor到beanFactory中的list

第六步 最后从容器中找出所有beanFactoryPostProcessor,防止再postProcessBeanFactory时有新产生并且未处理过的处理器
如果有的化依然按照优先级顺序加入执行,执行结果只有一个
在这里插入图片描述

registerBeanPostProcessors

与执行beanFactoryPostProcessor方法类似,已然按照优先级顺序从当前容器中找出来所有name执行,没有自定义的化默认只有这两个内置的,且都是PriorityOrder的

List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>();在这里插入图片描述
把上述处理器找出来并加入到beanFactory中(实际上只是加到了list中,后续可以直接从当前list中获取,不用从容器里拿)---- registerBeanPostProcessors

接着又直接加了一个ApplicationListenerDetector到集合中,未存在singletonObjects中(该类修饰符是默认的,不可在包外访问实例化)

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

这是真正创建非懒加载单例bean的方法,调用beanFactory.preInstantiateSingletons()

非FactoryBean的情况下,直接去getBean
先允许提前从提早缓存对象中拿,提早暴露的objects或objectFactories,对于自定义的单例第一次拿不到
在这里插入图片描述
接着经过一系列判断后,开始创建

          if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
				
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

getSingleton中会再次尝试从缓存单例池中拿,将当前bean标记为正在创建中,然后调用对象工厂方法createBean构造bean,将它加入到单例对象池中,并将提早引用池和工厂池中移除当前bean
在这里插入图片描述

在工厂方法中,先尝试是否可以有处理器提早生成一个对象(默认还是null),调用applyBeanPostProcessorsBeforeInstantiation ->有值 再applyBeanPostProcessorsAfterInitialization
执行当前所有(beanFactory中的处理器集合)后置处理器的postProcessBeforeInstantiation

// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

doCreateBean 去执行真正创建bean的过程
createBeanInstance -> 实例化bean对应的class
applyMergedBeanDefinitionPostProcessors->

  • 两个内置后置处理器CommonAnnotationBeanPostProcessor -> 处理PostConstruct,Predestroy, Resource等注解信息的封装
  • AutowiredAnnotationBeanPostProcessor->
    处理Autowired,Value等注解对应的file,method封装起来

判断是否需要提前暴露该对象引用(用于解决循环依赖),加到singletonFactories

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

populateBean ->填充bean的属性

  • InstantiationAwareBeanPostProcessor postProcessAfterInstantiationr处理器的调用
  • 判断注入模式resolvedAutowireMode ,AutowireCapableBeanFactory中的几种
  • InstantiationAwareBeanPostProcessor postProcessProperties 用于处理上一步封装好的InjectedElement的信息。包括common的ResourceElement, autowired的AutowiredFieldElement,AutowiredMethodElement等,如果没有要设置进来的对象,会从bean工厂中找,开始进行依赖对象bean的生命周期的创建

initializeBean ->调用初始化方法及生命周期回调
InitDestroyAnnotationBeanPostProcessor 是CommonAnnotationBeanPostProcessor的父接口
在这里插入图片描述

  • invokeAwareMethods -> BeanNameAware、BeanClassLoaderAware,BeanFactoryAware只有这三个接口,那么其他的aware接口是在哪里调用的呢?ApplicationContextAwareProcessor
  • applyBeanPostProcessorsBeforeInitialization-> 注意 这里会调用InitDestroyAnnotationBeanPostProcessor 解析的PostConstruct方法,以及ApplicationContextAwareProcessor 执行所有invoke Aware接口方法
    在这里插入图片描述
  • invokeInitMethods -> 实现了InitializingBean的方法,调用afterPropertiesSet;同时看bd中是否有自定义不重名的init method也调用
  • applyBeanPostProcessorsAfterInitialization-> AbstractAutoProxyCreator 会在这里进行aop动态代理包装

至此,bean的创建就已经结束了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值