【Spring 学习笔记】5 推断构造方法

Spring中的一个bean,需要实例化得到对象,而实例化就需要用到构造方法。这篇笔记主要记录Spring Bean生命周期中实例化Bean对象过程中推断构造方法的逻辑

一、回顾一下Spring Bean 的生命周期过程

Spring容器扫描class得到BeanDefinition,从而去生产Bean
1.根据class推断构造方法
2.根据推断出来的构造方法,反射,得到一个对象
3.填充对象中的属性(依赖注入)
4.如果对象中的某个方法被AOP了,那么则需要根据对象生成一个代理对象
5. 把最终生成的代理对象放入单例池(即singletonObjects)中。

二、 Bean中构造方法的业务场景有哪些

  1. 默认情况,用无参构造器,只有一个构造方法就用这一个
  2. 多个构造方法,程序中通过getBean()或者BeanDefinition.getConstructorArgumentValues()指定了构造方法参数,就使用与之匹配的构造方法
  3. 通过@Autowired注解指定了某个构造方法
  4. 没有如上情况则让Spring自动选择构造方法以及构造方法的入参值:
    使用AnnotationConfigApplicationContext,会使用构造方法进行实例化,那么Spring会根据构造方法的参数信息去寻找bean,然后传给构造方法
    使用ClassPathXmlApplicationContext,表示使用XML的方式来使用bean,要么在XML中指定构造方法的参数值(手动指定),要么配置autowire=constructor让Spring自动去寻找bean做为构造方法参数值。

三、源码

源码的思维导入:

https://www.processon.com/v/64b0f88ab856374c5c180238
在这里插入图片描述

源码主要方法逻辑分析

AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors()
推断出被@Autowired注释的可用的构造方法,方法逻辑如下:

  1. 获取Bean中的所有构造方法 rawCandidates = beanClass.getDeclaredConstructors();
  2. 当前遍历的构造方法是否写了@Autowired —findAutowiredAnnotation(candidate);
  3. .没有Autowired注解的构造方法
    • 没有添加了@Autowired注解的构造方法,并且类中只有一个构造方法,并且是有参的.返回这个构造方法。
    • 如果有多个有参、并且没有添加@Autowired的构造方法,是会返回null。
    • 只有一个无参构造器返回null。
  4. 有Autowire注解的构造方法
    • 有一个Request= true(只有要给构造方法上有Autowire)返回此构造方法
    • 有多个Request=ture,抛异常
    • 有一个Request= true其余为false, 抛异常
    • request 全是false,返回所有构造器和无参构造器

autowireConstructor()

  1. 先检查是否指定了具体的构造方法和构造方法参数值,或者在BeanDefinition中缓存了具体的构造方法或构造方法参数值,如果存在那么则直接使用该构造方法进行实例化
  2. 如果没有确定的构造方法或构造方法参数值,那么
  • 如果没有确定的构造方法,那么则找出类中所有的构造方法
  • 如果只有一个无参的构造方法,那么直接使用无参的构造方法进行实例化
  • 如果有多个可用的构造方法或者当前Bean需要自动通过构造方法注入
    根据所指定的构造方法参数值,确定所需要的最少的构造方法参数值的个数
  • 对所有的构造方法进行排序,参数个数多的在前面
  • 遍历每个构造方法
  • 如果不是调用getBean方法时所指定的构造方法参数值,那么则根据构造方法参数类型找值
  • 如果时调用getBean方法时所指定的构造方法参数值,就直接利用这些值
  • 如果根据当前构造方法找到了对应的构造方法参数值,那么这个构造方法就是可用的,但是不一定这个构造方法就是最佳的,所以这里会涉及到是否有多个构造方法匹配了同样的值,这个时候就会用值和构造方法类型进行匹配程度的打分,找到一个最匹配的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值