Spring的构造方法推断

简介: Spring的构造方法推断



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

  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. 如果根据当前构造方法找到了对应的构造方法参数值,那么这个构造方法就是可用的,但是不一定这个构造方法就是最佳的,所以这里会涉及到是否有多个构造方法匹配了同样的值,这个时候就会用值和构造方法类型进行匹配程度的打分,找到一个最匹配的

相关文章
|
6月前
|
缓存 Java 测试技术
Spring5源码(22)-Spring通过有参构造方法实例化单例bean
Spring5源码(22)-Spring通过有参构造方法实例化单例bean
91 0
|
6月前
|
缓存 Java Spring
Spring5源码(21)-Spring通过无参构造方法实例化单例bean
Spring5源码(21)-Spring通过无参构造方法实例化单例bean
61 0
|
6月前
|
Java Spring
[Spring源码] 浅析 SpringApplication`的构造方法
[Spring源码] 浅析 SpringApplication`的构造方法
|
XML 缓存 Java
Spring之推断构造方法
Spring之推断构造方法
49 0
|
Java Spring
2021-08-09构造方法注入,项目搭建,通过注释注入,注解扫描器,spring,ioc结束,AOP(二)
2021-08-09构造方法注入,项目搭建,通过注释注入,注解扫描器,spring,ioc结束,AOP
189 0
|
Java Spring
2021-08-09构造方法注入,项目搭建,通过注释注入,注解扫描器,spring,ioc结束,AOP(一)
2021-08-09构造方法注入,项目搭建,通过注释注入,注解扫描器,spring,ioc结束,AOP
187 0
|
缓存 Java 开发者
Spring源码(八)-构造方法实例化Bean-createBeanInstance
各位小伙伴好,这是 Spring 源码系列的第八篇文章。本篇篇幅较长(五千八百字),建议收藏慢慢品尝。
656 1
|
Java 程序员 网络安全
spring4.1.8初始化源码学习三部曲之一:AbstractApplicationContext构造方法
学习spring初始化过程是深入了解spring过程中重要的一步,今天我们就以一个简单的demo为例来学习spring初始化的源码
117 0
spring4.1.8初始化源码学习三部曲之一:AbstractApplicationContext构造方法
|
Java Android开发 数据安全/隐私保护
spring练习,使用Eclipse搭建的Spring开发环境,属性注入通过构造方法方式实现,模拟用户的正常登录。
spring练习,使用Eclipse搭建的Spring开发环境,属性注入通过构造方法方式实现,模拟用户的正常登录。
118 0
spring练习,使用Eclipse搭建的Spring开发环境,属性注入通过构造方法方式实现,模拟用户的正常登录。
|
Java Spring 数据格式