春のコンストラクタ注入型のあいまいさ

Springのコンストラクター注入型のあいまいさ

Springフレームワークでは、クラスに同じ数の引数を持つ複数のコンストラクターが含まれていると、常にconstructor injection argument type ambiguitiesの問題が発生します。

問題

この顧客Beanの例を見てみましょう。 2つのコンストラクターメソッドが含まれており、どちらも異なるデータ型の3つの引数を受け入れます。

package com.example.common;

public class Customer
{
    private String name;
    private String address;
    private int age;

    public Customer(String name, String address, int age) {
        this.name = name;
        this.address = address;
        this.age = age;
    }

    public Customer(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    //getter and setter methods
    public String toString(){
        return " name : " +name + "\n address : "
               + address + "\n age : " + age;
    }

}

Spring Bean構成ファイルで、名前に「example」、住所に「188」、年齢に「28」を渡します。



    

        
            example
        

        
            188
        

        
            28
        
        

実行して、あなたの期待する結果は何ですか?

package com.example.common;

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

public class App
{
    public static void main( String[] args )
    {
        ApplicationContext context =
          new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});

        Customer cust = (Customer)context.getBean("CustomerBean");
        System.out.println(cust);
    }
}

出力

 name : example
 address : 28
 age : 188

結果は期待したものではなく、最初のコンストラクターではなく、2番目のコンストラクターが実行されます。 Springでは、引数タイプ「188」はintに変換できるため、Springはそれを変換し、2番目のコンストラクターを取得します。これは、ストリングであると仮定してもです。

さらに、Springが使用するコンストラクタを解決できない場合、次のエラーメッセージが表示されます

constructor arguments specified but no matching constructor
found in bean 'CustomerBean' (hint: specify index and/or
type arguments for simple parameters to avoid type ambiguities)

溶液

修正するには、次のようなtype属性を使用して、コンストラクターの正確なデータ型を常に指定する必要があります。



    

        
            example
        

        
            188
        

        
            28
        

    

もう一度実行して、期待どおりの結果が得られます。

出力
 name : example
 address : 188
 age : 28

Note
上記のコンストラクター注入タイプのあいまいさの問題を回避するために、コンストラクター引数ごとにデータ型を明示的に宣言することは常に良い習慣です。