加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 构造函数参数解析

发布时间:2020-12-15 04:13:02 所属栏目:Java 来源:网络整理
导读:我最近开始在3.2版本上工作.我试图理解构造函数参数解析,以防何时通过构造函数注入传递依赖项.我创建了以下示例. package com.springinaction.springidol;public interface Performer { void perform();}package com.springinaction.springidol;public class
我最近开始在3.2版本上工作.我试图理解构造函数参数解析,以防何时通过构造函数注入传递依赖项.我创建了以下示例.

package com.springinaction.springidol;

public interface Performer {
    void perform();
}
package com.springinaction.springidol;

public class Juggler implements Performer {

    private int beanBags=3;
    private String name;

    public Juggler(){
    }

    public Juggler(String name,int beanBags){
        System.out.println("First constructor gets called");
        this.beanBags=beanBags;
        this.name=name;
    }

    public Juggler(int beanBags,String name){
        System.out.println("Second constructor gets called");
        this.beanBags=beanBags;
        this.name=name;
    }

    public void perform(){
    System.out.println("JUGGLING "+beanBags+name+" BEANBAGS");
    }
}

请查看下面我使用的spring配置文件的实例.

<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="duke" class="com.springinaction.springidol.Juggler">
    <constructor-arg value="Jinesh" />
    <constructor-arg value="77" />
</bean>

在上面的场景中,调用的构造函数是第一个构造函数.但之后我稍微更改了xml文件并为两个参数添加了type属性.

<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="duke" class="com.springinaction.springidol.Juggler">

<constructor-arg type="java.lang.String" value="Jinesh" />
<constructor-arg type="int" value="77" />

</bean>

</beans>

在上面的例子中,spring调用的构造函数是第二个构造函数.我不明白为什么spring决定调用第二个构造函数而不是第一个构造函数?在上面的例子中,当我们传递type属性时spring如何决定调用哪个构造函数?

解决方法

Spring使用ConstructorResolver实例来解析用于实例化类的构造函数.它调用autowireConstructor()方法来确定它.您可以在线找到源代码.旧版本,here.如果您有源(使用maven),您可以自己调试并完成它.

在该方法中,它尝试使用ArgumentsHolder#getTypeDifferenceWeight()方法确定指定参数与控制器中参数之间的差异.在我们的例子中,它将返回值0,因为参数匹配(即使是以不同的顺序).

该值与minTypeDiffWeight值(最初为Integer.MAX_VALUE)进行比较.如果它更小,则被评估的当前构造函数将获得优先级,并且该值将替换minTypeDiffWeight.这个方法通过所有Class’构造函数继续进行,再次与minTypeDiffWeight进行比较.由于两个构造函数都将赋值0(0不小于0),因此使用找到的第一个.

正好

Juggler.class.getDeclaredConstructors();

返回一个类似的数组

[public Test.Juggler(int,java.lang.String),public Test.Juggler(java.lang.String,int),public Test.Juggler()]

其中第二个(声明的)构造函数首先出现. getDeclaredConstructors()方法javadoc声明

The elements in the array returned are not sorted and are not in any
particular order.

所以这只是巧合.因为参数类型匹配,所以Spring选择它在该数组中找到的第一个构造函数.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读