Spring源码解析6-spring的bean创建流程实例化

本文深入剖析了Spring框架中bean的创建流程,从finishBeanFactoryInitialization()开始,包括类型转换器初始化、bean实例化、依赖注入等多个步骤,详细解释了如doGetBean()、createBean()等关键方法的作用,以及在创建过程中如何处理构造器、工厂方法、依赖关系等复杂情况。

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

spring的bean创建流程实例化,通过获取构造器,反射创建bean,分配空间

 

refresh()中的finishBeanFactoryInitialization(), 完成此上下文bean工厂的初始化,初始化所有剩余的单例bean(非懒加载的)

 

finishBeanFactoryInitialization()

 

1、为上下文初始化类型转换器,ConversionService有3种转换器实现类,1对1转换,1对N转换,N对N转换

2、beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析,之前注册嵌入解析器是在refresh的invokeBeanFactoryPostProcessors()调用各种beanFactory增强器已经注册了

3、尽早初始化loadTimeWeaverAware bean,以便尽早注册它们的转换器

4、禁止使用临时类加载器进行类型匹配

5、冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理,因为将要进行实例化对象

6、实例化剩下的单例对象,有些对象是BeanFactoryPostProsessor、或者BeanPostProsessor,在之前已经通过getBean()方法进行实例化过

preInstantiateSingletons() 实例化剩下的单例对象

 

getMergedLocalBeanDefinition(),在实例化之前,把所有基础的beanDefinition对象转换成RootBeanDefinition对象进行缓存定义信息,后续在需要实例化的时候直接获取定义信息,定义信息中如果包含了父类,那么必须要先创建父类后才能创建子类

getBean() 获取bean实例

 

doGetBean() ,实际获取bean的方法,也是触发依赖注入的方法

 

transformedBeanName(name),提取对应的beanName,因为当bean对象实现FactoryBean接口之后就会变成&beanName,如果存在别名,也需要把别名进行转换

getSingleton(beanName),提前检查容器中的单例缓存是否有手动注册的单例对象,跟循环依赖有关联,如果找到了直接返回对象,没有就创建。

getObjectForBeanInstance(),返回对象的实例,当实现了FactoryBean接口的对象,需要获取具体的对象的时候就需要此方法来进行获取了

 

isPrototypeCurrentlyInCreation(),检测是否循环依赖,是则抛出异常

如果bean定义不存在,就检查父工厂是否有,如果beanDefinitionMap中也就是在所有已经加载的类中不包含beanName,那么就尝试从父容器中获取。都是调用getBean,尝试获取bean。

markBeanAsCreated(),为beanName标记为已经创建(或将要创建),表示要创建bean,此处在集合中做一个记录

 

getMergedLocalBeanDefinition(),BeanDefinition对象的转换,当从xml文件中加载beandefinition对象的时候,封装的对象是GenericBeanDefinition,此处要做类型转换,如果是子类bean的话,会合并父类的相关属性

checkMergedBeanDefinition(),检查mbd的合法性,不合格会引发验证异常。

查看是否有依赖的bean,有依赖则优先实例化依赖的bean。

 

getSingleton(),参数是一个lambda表达式,

getSingleton(String beanName, ObjectFactory singletonFactory),参数是beanName跟ObjectFactory,只有在调用ObjectFactory的getObject()方法,才会回调lambda表达式里面的createBean()方法。

 

 

调用createBean()方法

 

resolveBeanClass(),根据className来解析成class对象

prepareMethodOverrides(),验证及准备覆盖的方法,lookup-method replace-method,当需要创建的bean对象中包含了lookup-method和replace-method标签的时候,会产生覆盖操作。

 

resolveBeforeInstantiation(),给BeanPostProcessors一个机会来返回代理来替代真正的实例,应用实例化前的前置处理器,用户自定义动态代理的方式,针对于当前的被代理类需要经过标准的代理流程来创建对象

 

resolveBeforeInstantiation(),判断当前mbd是否是合成的,只有在实现aop的时候synthetic的值才为true,并且是否实现了InstantiationAwareBeanPostProcessor接口

applyBeanPostProcessorsBeforeInstantiation(),InstantiationAwareBeanPostProcessor类型的处理器处理,返回的是一个代理对象,下面的doCteateBean()方法不执行了

 

 

 

BeanPostProcessor接口的2个方法

1、初始化方法调用前要进行的处理逻辑

2、在初始化方法指定后要进行的处理逻辑

 

InstantiationAwareBeanPostProcessor接口的三个方法

1、在bean实例化之前调用

2、在bean实例化之后调用

3、当使用注解的时候,通过这个方法来完成属性的注入

 

doCreateBean() 实际创建bean的调用

 

createBeanInstance(),根据执行bean使用对应的策略创建新的实例,如,工厂方法,构造函数主动注入、简单初始化

 

obtainFromSupplier(),判断当前beanDefinition中是否包含实例供应器,此处相当于一个回调方法,利用回调方法来创建bean

调用Supplier instanceSupplier.get(),函数式接口,会调用lambda表达式的方法,创建对象成功

 

自定义BeanFactoryPostProcessor,设置Supplier

 

 

createBeanInstance(),如果工厂方法不为空则使用工厂方法初始化策略

 

instantiateUsingFactoryMethod(),通过工厂方法实例化,先获取构造器解析器,然后用工厂方法进行实例化

 

 

 

instantiateBean(),使用默认无参构造函数创建对象,如果没有无参构造且存在多个有参构造且没有@AutoWired注解构造,会报错

 

InstantiationStrategy 实例化策略接口

SimpleInstantiationStrategy 简单的对象实例化策略,实现InstantiationStrategy

CglibSubclassingInstantiationStrategy继承SimpleInstantiationStrategy, beanFactory中的对象默认实例化策略

 

instantiate(),获取实例化策略并且进行实例化操作,如果发现是有方法重载的,就需要用cglib来动态代理,如果没有就直接获取默认构造方法实例化 。

 

 

获取实例化的bean后,将它包装成BeanWrapper的类。

BeanWrapper是spring中的核心接口,是spring中的一个包装类,具有单独或者批量获取和设置属性值,获取属性描述符以及查询属性可读可写的能力,还可以完成类型的转换。

以上都已经执行完createBeanInstance()

applyMergedBeanDefinitionPostProcessors(),允许beanPostProcessor去修改合并的beanDefinition,MergedBeanDefinitionPostProcessor后置处理器修改合并bean的定义

 

applyMergedBeanDefinitionPostProcessors(),应用MergedBeanDefinitionPostProcessors类型的beanPostProcessor到指定的beanDefinition中,执行postProcessMergedBeanDefinition方法

 

遍历需要执行的bp有CommonAnnotationBeanPostProcessor,AutowiredAnnotationBeanPostProcessor,InitDestroyAnnotationBeanPostProcessor,解析注解,合并到definition

 

postProcessMergedBeanDefinition()

 

postProcessMergedBeanDefinition(),处理@PostConstruct和@PreDestroy注解

 

findLifecycleMetadata(),调用方法获取生命周期元数据并保存

 

buildLifecycleMetadata(),构建完生命周期元数据后,checkConfigMembers()然后注册回去

 

findResourceMetadata(),找出beanType所有被@Resource标记的字段和方法封装到InjectionMetadata中

 

以上applyMergedBeanDefinitionPostProcessors()完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值