0

私は春が初めてです。以下のように、1 つの Bean クラスと構成ファイルを作成しました。

Beans.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.xsd">

    <bean id="employee" class="com.asd.bean.Employee">
        <constructor-arg index="0" type="java.lang.String" value="kuldeep" />
        <constructor-arg index="1" type="java.lang.String" value="1234567" />
    </bean>

</beans>

従業員.java

package com.asd.bean;

public class Employee {

    private String name;
    private String empId;

    public Employee() {
        System.out.println("Employee no-args constructor");
    }

    Employee(String name, String empId)
    {
        System.out.println("Employee 2-args constructor");
    this.name=name;
    this.empId=empId;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the empId
     */
    public String getEmpId() {
        return empId;
    }

    /**
     * @param empId the empId to set
     */
    public void setEmpId(String empId) {
        this.empId = empId;
    }

    public String toString() {
        return "Name : "+name+"\nEID : "+empId; 

    }

}

ApplicationContext を使用して Bean を取得しようとすると、次の例外が発生します。

スレッド「メイン」での例外 org.springframework.beans.factory.BeanCreationException: クラスパスリソースで定義された名前「employee」を持つ Bean の作成中にエラーが発生しました [Problem.xml]: 2 つのコンストラクター引数が指定されましたが、一致するコンストラクターが Bean「employee」に見つかりませんでした (ヒント: 型のあいまいさを避けるために、単純なパラメーターにはインデックス/型/名前の引数を指定してください)

デフォルトのコンストラクターからパブリックを削除すると、正常に機能し、両方のコンストラクターをパブリックにする場合でも機能します。この動作を示している理由を説明してください???

前もって感謝します。

4

1 に答える 1

2

これが 3.2.4 で動作することを確認しただけで、3.0.0 では動作しません。ここで問題となっている実装はConstructorResolver#autowireConstructor()3.0.0 です。このメソッドは、使用する正しいコンストラクターを解決するために使用されます。この実装では、 whichConstructorを使用してすべての Bean クラスのインスタンスを取得しClass#getDeclaredConstructors()ます。

この Class オブジェクトによって表されるクラスによって宣言されたすべてのコンストラクターを反映する Constructor オブジェクトの配列を返します。返される配列の要素はソートされておらず、特定の順序でもありません。

次に、これらの配列を呼び出して並べ替えます

AutowireUtils.sortConstructors(candidates);

どれの

指定されたコンストラクターを並べ替え、パブリック コンストラクターと、最大の引数を持つ「貪欲な」コンストラクターを優先します。結果には、最初にパブリック コンストラクターが含まれ、引数の数が減少し、次に非パブリック コンストラクターが含まれ、引数の数が減少します。

つまり、引数なしのコンストラクターが最初に表示されますが、必要な引数がないため、autowireConstructor()メソッドはすぐに をスローしException、失敗します。回避策は、他のコンストラクターの可視性の制限を緩和することです。

3.2.4 の実装では、同じようにコンストラクターを並べ替えますが、引数の数と一致しないパラメーター リストを持つコンストラクターが見つかった場合、それはスキップされます。この場合、それは機能します。引数のないコンストラクターはスキップされ、2 つの引数のコンストラクターが照合され、解決され、使用されます。

于 2013-11-12T06:28:54.233 に答える