SpringBean的加载

1.转换对应的beanName

1.1去除FactoryBean的修饰符&
1.2取指定alias所表示的最终beanName。

2.尝试从缓存中加载单例

在这里插入图片描述
首先尝试在缓存中加载,然后在尝试从singletonFactories中加载。
创建的时候避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时需要依赖上个bean,则直接使用ObjectFactory。

5.3从bean的实例中获取对象

在这里插入图片描述
1.对FactoryBean正确性的验证
2.对非FactoryBean不做处理
3.对bean进行转换
4.将从Factory中解析bean的工作委托给getObjectFromFactoryBean
在这里插入图片描述
如果返回的bean是单例,就保证全局唯一,同时也因为是单例,所以不需要重复创建,可以使用缓存来提高性能,以供下次直接使用。否则直接创建使用。
使用doGetObjectFromFactoryBean方法创建。该方法就是实现favtoryBean.getObject方法的功能。

5.4获取单例

在这里插入图片描述
1.检查缓存是否已经加载过了
2.若没有加载,则记录beanName的正在加载状态
3.加载单例前记录加载状态
4.实例化bean
5.加载单例后的处理方法调用,移除加载状态
6.将结果记录至缓存中,并删除加载bean过程中所记录的各种辅助状态
7.返回处理结果

5.5准备创建bean

在这里插入图片描述
该函数主要步骤:
1.根据设置的class属性或者根据className来解析Class
2.对override属性进行标记及验证
3.应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作。
如果创建了代理或者说重写了AbstractAutowireCapableBeanFactory的resolveBeforeInstantiation方法并在方法resolveBeforeInstantiation中改变了bean,则直接返回就可以了,否则需要进行常规创建bean,执行第4步。
4.创建bean

5.6循环依赖

5.6.1构造器循环依赖

Spring将每一个正在创建的bean标识符放在“当前创建bean池”中,构造器循环依赖会创建已在当前创建bean池的bean,会抛出错误。

5.6.2setter循环依赖

通过Spring容器提前暴露刚完成构造器注入但未完成其他步骤(如setter注入)的bean来完成的,而且只能解决单例作用域的bean循环依赖。

5.6.3prototype范围的依赖处理

Spring容器无法完成依赖注入,因为Spring容器不进行缓存“prototype”作用域的bean,因此无法提前暴露一个创建中的bean。

5.7创建bean

1.如果是单例则需要首先清除缓存
2.实例化bean,将BeanDefinition转换为BeanWrapper
2.1如果存在工厂方法则使用工厂方法进行初始化
2.2如果一个类有多个构造函数,根据参数锁定构造函数并进行初始化
判断过程是个比较消耗性能的步骤,所以采用缓存机制,如果已经解析过了则不需要重复解析而是直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值去取。否则需要再次解析,并将解析结果添加至RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod中。
实现该功能的是函数autowireConstructor,该函数步骤如下:
1.构造函数参数的确定
根据传入的explicitArgs参数判断
缓存中获取:缓存中的值可能是原始值也可能是最终值,会通过类型转换器过滤参数以确保参数类型与对应的构造函数参数类型完全对应
配置文件获取
2.构造函数的确定
按照public构造函数优先参数数量降序、非public构造函数参数数量降序进行排序
配置文件中还支持指定参数名称进行设定参数值得情况,所以首先确定构造函数参数名称。获取构造函数参数名称一是通过注解的方式直接获取,另一种是使用Spring提供的工具类。构造函数、参数名称、参数类型、参数值都确定后就可以锁定构造函数以及转换对应的参数类型。
3.根据确定的构造函数转换对应的参数类型
4.构造函数不确定性的验证
不同构造函数参数为父子关系
5.根据实例化策略和得到的构造函数以及构造函数参数实例化Bean
2.3如果即不存在工厂方法也不存在带有参数的构造函数,则使用默认构造函数
实现该功能的是函数instantiateBean,该函数根据实例化策略和得到的构造函数以及构造函数参数实例化Bean
实例化策略:判断是否有hasMethodOverrides属性,如果没有则说明用户没有使用replace和lookup的配置方法,直接使用反射方式,否则使用动态代理的方式将包含两个特性所对应的逻辑的拦截增强器设置进去,这样才可以保证在调用方法的时候会把相应的拦截器增强,返回值为包含拦截器的代理实例
3.MergedBeanDefinitionPostProcessor的应用
bean合并后的处理,@Autowired通过此方法实现诸如类型的与解析
4.依赖处理(条件单例,允许循环依赖、bean正在创建)
类A中属性包含类B,类B中属性包含类A。
先创建beanA,填充A属性,创建beanB,填充B属性,在B中创建依赖A时通过ObjectFactory提供的实例化方法中断A中的属性填充,使B中持有的A仅仅是刚刚初始化并没有填充任何属性的A,最后因为A与B中的A所表示的属性地址一样,A创建好的属性填充可以通过B中的A获取。
5.属性填充
5.1.InstantiationAwareBeanPostProcessor 处理器的postProcessAfterInstantiation函数的应用,此函数可以控制程序是否继续进行属性填充。在属性注入前最后的机会改变bean。
5.2.根据注入类型(byName/byType),提取依赖的bean,并统一存到PropertyValues中。
5.2.1autowireByName
通过递归调用getBean()实例化
5.2.2autowireByType
寻找类型匹配的bean注入到集合中,寻找类型的匹配执行顺序:首先使用解析器进行解析,如果没有成功,再次对不同类型进行不同情况的处理。
5.3应用InstantiationAwareBeanPostProcessor 处理器的postProcessPropertyValues方法,对属性获取完毕填充前对属性的再次处理,典型的应用是RequiredAnnotationBeanPostProcess类中对属性的验证。
5.4将所有PropertyValues中的属性填充至BeanWrapper中。
6.bean的初始化方法(配置init-method或者InitializingBean接口)
执行顺序是先InitializingBean接口的afterPropertiesSet方法,后执行init-method,前后都有方法进行响应的处理。
6.循环依赖检查
7.注册DisposableBean
如果配置了destroy-method,这里需要注册一遍销毁时调用
8.完成创建并返回

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值