《Spring框架源码系列》--Spring的构造方法推断

目录

在程序中使用构造方法的方式

构造方法推断流程

源码:

1.    构造方法缓存的使用判断

 2.   构造方法删选

 3.   构造方法推断


在程序中使用构造方法的方式

  1. 如果程序员不做任何处理,则默认用无参构造,或者只有一个构造方式,那就用那个。
  2. 如果程序员指定了构造方法参数,比如通过getbean()或者BeanDefinition.getConstructorArgumentValues()指定,那就根据入参匹配构造方法,默认匹配不到就报错。
  3. 在spring的xml中使用autowide="constructor"。则会让spring自动寻找构造方法。
  4. 在程序中使用@autowide注解在某个构造方法上,则优先使用这个构造方法,构造方法的参数由spring自动寻找。

构造方法推断流程

  1. 如果程序员指定了构造方法入参值,通过getbean()或者BeanDefinition.getConstructorArgumentValues()指定,那就优先根据入参匹配构造方法,默认情况下如果找不到那就报错,也可修改beanDefinition的ResolvedAutowireMode值为AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR,此时spring会选择参数个数大于传入参数个数最多的构造方法。程序员指定构造方法参数只对非懒加载的单例bean生效。
  2. 默认情况下,即程序员没有指定构造方法参数,程序中也没有加@Autowide或@Lookup注解,如果只有一个构造方法,那就用那个,构造方法的参数由spring自动寻找注入(先ByType后ByName)或在xml中程序员指定。如果有多个构造方法,则只能用无参构造方法,没有无参构造方法则报错。
  3. 如果程序员通过@Autowide注解指定了某个构造方法,这时由spring自动去寻找该构造方法的入参值。原则是,如果只有一个构造方法上加了@Autowide(require=true)那就用这个,如果有一个构造方法上加了@Autowide(require=true)的同时,还有其他构造方法加了@Autowide,无论其require等于true还是false,都会报错。如果有多个构造方法上加了@Autowide(require=false),则不管存不存无参构造方法,默认使用参数最多的构造方法。如果参数最多的构造方法存在多个,则根据得分匹配,所谓的得分匹配是根据构造方法的参数类型匹配度匹配得分。这里有两种模式,默认为宽松模式。在宽松模式下不仅仅看找到的bean是否需要类型转换,还看bean的父子级关系,越需要类型转换、父子级差的越远,则得分越高,说明匹配度越低。而在严格模式下,只看是否需要类型转换,越需要类型转换,则得分越高,说明匹配度越低,在严格模式下得分相同就会抛异常。

源码:

1.    构造方法缓存的使用判断

如果获取bean的时候没有指定构造方法的入参,就会使用缓存,否则不会用缓存。具体做法为先看缓存里有没有构造方法及构造方法对应的注入对象,如果有就用缓存的。没有就进行下一步的推断。

 2.   构造方法删选

      这一步主要是检查构造方法是否有@Lockup/@Autowide注解,如果有,优先根据这些注解推断出构造方法。

   具体规则为:

 3.   构造方法推断

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

季风泯灭的季节

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值