spring推断构造方法

258 阅读3分钟

本节主要讲解spring怎么去实例化对象的,也就是推断构造方法。

一、实例化对象的方式

首先我们需要知道spring容器来实例化一个对象时,它内部有如下四种方式来进行实例化一个对象:

默认情况

1、如果对象只有一个构造方法,则直接使用这个构造方法。

2、如果有多个构造方法,则直接使用无参构造方法,如果没有无参构造方法,实例化会直接报错。

使用注解方式

如果使用了@Autowired注解:

  • 如果有多个加了@Autowired的构造方法,必须都为false,否则直接报错。然后spring自行选择构造方法以及构造方法的参数值

  • 只能有一个@Autowired,并且为true的构造方法,spring自行选择构造方法的的入参值。

构造注入方式

1、如果使用了构造注入 autowire=“constructor”,spring则自动的选择构造方法以及入参值。

      这种一般是通过xml方式进行配置bean,如下:

   当然也可以通过Beandefinition进行配置,如下:

2、如果使用了构造注入 autowire=“constructor”,并且指定了实例化的参数。

      那么spring首先选择构造方法,并把给定的参数值尽量与构造方法需要的参数匹配上(当然这里spring会进行参数类型转换,如果转换失败,将会报错),如果不能匹配,则从spring容器中进行获取。

指定构造方法参数

spring会自行选择构造方法,并尽可能的把给定的参数与构造方法需要的参数进行匹配上(当然这里spring会进行参数类型转换,如果转换失败,将会报错),代码如下所示:

二、源码分析

     接下来我们将会通过源码来进行分析,spring推断构造方法的整个过程。为了方便大家看懂源码,源码中有很多细枝末节东西,我都会直接忽略掉。

1、主要逻辑

首先直接来到spring创建对象的方法入口

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance

这个方法主要做了三件事:

  • 1、获取加了@Autowired相关的逻辑的构造方法

  • 2、通过上面获取到的构造方法列表推断构造方法,以及使用构造参数进行实例化

  • 3、如果没有找到构造方法,则直接使用无参构造方法进行实例化

2、通过@Autowired获取相关构造方法

 主要处理逻辑则是determineConstructorsFromBeanPostProcessors()方法,这里其实是spring通过bean的后置处理器进行处理,具体的调用逻辑在

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors

      有兴趣的同学可以研究下AutowiredAnnotationBeanPostProcessor中的处理逻辑,大致的推断构造方法不同情况如下:

3、推断构造方法并实例化

  推断构造方法的主要处理逻辑在

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireConstructor

最终调用到

org.springframework.beans.factory.support.ConstructorResolver#autowireConstructor

此方法主要做了以下3件事:

  • 1、判断是否传入构造参数,以及是否在Beandefinition中设置了构造参数,并计算出构造参数最小个数

  • 2、依次遍历构造方法,根据最小构造参数判断,找到大于等于最小参数个数的构造方法,并构造出构造方法需要的构造参数

  • 3、计算出最适合的构造方法,并完成实例化

具体源码如下:

第一步:计算出最小参数个数

第二步:依次遍历构造方法

第三步:计算评分

实例化: