spring - 当构造函数存在歧义时,Spring中选择构造函数的逻辑是什么

标签 spring

首先我需要告诉我知道如何使用 Spring 配置文件中的类型和索引来解决这个问题。但我想了解当存在歧义构造函数时 spring 如何选择构造函数

Pojo类

package a.b.c;

public class Square {

    private String color;
    private int sideLength;

    public Square(String color, int sideLength) {
        System.out.println("Constructor id #1");
        this.sideLength = sideLength;
        this.color = color;
    }

    public Square(int sideLength, String color) {
        System.out.println("Constructor id #2");
        this.sideLength = sideLength;
        this.color = color;
    }

    public Square(Integer sideLength, String color) {
        System.out.println("Constructor id #3");
        this.sideLength = sideLength;
        this.color = color;
    }

    public void draw() {
        System.out.println("square color : " + color + ", sideLenth : " + sideLength);
    }

}

ApplicationContext.xml

<?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-2.5.xsd">

    <bean id="square" class="a.b.c.Square">
        <constructor-arg type="java.lang.String" value="red" />
        <constructor-arg type="int" value="10" />
    </bean>
</beans>

调用类

package a.b.c;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Application {

    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");

        Square square = (Square) context.getBean("square");
        square.draw();

    }

}

通过这种安排,它选择#2 构造函数

如果在源文件中交换构造函数位置,则无需更改任何配置

package a.b.c;

public class Square {

    private String color;
    private int sideLength;

    public Square(int sideLength, String color) {
        System.out.println("Constructor id #2");
        this.sideLength = sideLength;
        this.color = color;
    }

    public Square(String color, int sideLength) {
        System.out.println("Constructor id #1");
        this.sideLength = sideLength;
        this.color = color;
    }

    public Square(Integer sideLength, String color) {
        System.out.println("Constructor id #3");
        this.sideLength = sideLength;
        this.color = color;
    }

    public void draw() {
        System.out.println("square color : " + color + ", sideLenth : " + sideLength);
    }

}

除了方法位置之外,没有任何变化。 现在它选择#1构造函数

我的问题是当出现歧义时选择构造函数的逻辑是什么。

注意:我知道这可以使用index.html来解决。

最佳答案

我认为您正在寻找它如何在代码级别进行选择。但我不知道你为什么担心它。但我个人很欣赏你为实现这一点而付出的努力,而不是随机相信。 我不确定我能否给出您正在寻找的确切答案。但我会引导你。 spring源码在github上。这样你就可以检查自己。

当它没有引导(使用索引)多个构造函数时,Spring 会混淆选择什么。它不可能是随机的。正如你所说,它必须有逻辑。这就是它的工作原理。

spring有类调用ConstructorResolver。当 spring 需要解析构造函数时,它就会去那里。在您的情况下,3 个构造函数符合资格。所有人都具有相同的同等资格。由于所有内容都是无引导的,因此它会进入 Autowiring 模式来解析候选构造函数。

所以它首先使用 java.util.comparator 对所有 3 个构造函数进行排序。之后它会尝试解析您的所有 3 个连接器。 (createArgumentArray) 但 Integer 构造函数会根据您给出的值生成异常。熄灭后只剩下 2 个。 然后计算类型差异权重来选择方法。 (我认为我不应该在这里解释这个逻辑)它尝试对转换后的参数和原始参数进行类型差异权重。如果原始重量更好,则将成为候选重量。

我希望我已经给出了预期的答案。你可以从这里继续。如果还有什么不清楚的请在下面评论。

编辑:sortConstructors考虑优先使用公共(public)构造函数和具有最大参数数量的构造函数。结果将首先包含参数数量逐渐减少的公共(public)构造函数,然后是参数数量逐渐减少的非公共(public)构造函数。但在上述情况下排序不会生效。这就是当源更改时更改执行方法的原因。

关于spring - 当构造函数存在歧义时,Spring中选择构造函数的逻辑是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34075512/

相关文章:

Java Spring上传文件到FTP服务器

java - Spring过滤器作为基于Java注释的bean

java - Spring 4.x 与 Spring Integration 4.X ClassLoader 问题

eclipse - 在 Spring + eclipse 中配置 JUnit 4

java - Spring MVC 表单验证消息未加载

java - Spring中SMTP邮件程序的配置

java - 尚未定义 spring.config.import 属性 -> 将 spring-cloud-starter-config 添加到 pom.xml 后

java - Spring JPA,更新实体属性时的附加数据库操作

java - 如何在分布在多个文件上的 Spring Security 中订购多个 <http> 元素

java - 在 Spring 中访问远程 JNDI