1. ホーム
  2. java

[解決済み] Springの@Autowiredの使い方を理解する

2022-03-17 19:06:29

質問

Spring 3.0.xのリファレンスドキュメントを読んで、Spring Autowiredアノテーションを理解しようとしているところです。

3.9.2 @Autowiredと@Inject

以下の例が理解できません。動作させるためには、XMLの中で何かする必要があるのでしょうか?

例1

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

    // ...
}

例2

public class MovieRecommender {

    private MovieCatalog movieCatalog;

    private CustomerPreferenceDao customerPreferenceDao;

    @Autowired
    public void prepare(MovieCatalog movieCatalog,
                    CustomerPreferenceDao customerPreferenceDao) {
        this.movieCatalog = movieCatalog;
        this.customerPreferenceDao = customerPreferenceDao;
    }

    // ...
}

同じインターフェースを実装し、同じクラスを使用する2つのクラスを自動配線するにはどうしたらよいでしょうか。

class Red implements Color
class Blue implements Color

class myMainClass{
    @Autowired 
    private Color color;

    draw(){
        color.design(); 
    } 
}

どのデザインメソッドが呼び出されるのでしょうか?BlueではなくRedクラスのデザインメソッドが呼ばれるようにするにはどうすればよいですか?

どのように解決するのですか?

TL;DR

@Autowired アノテーションは、XML ファイル (あるいは他の方法) の中で自分で配線を行う必要をなくし、ただ何がどこに注入される必要があるかを見つけてそれを行ってくれます。

詳しい説明

@Autowired アノテーションを使用すると、他の場所で何を注入するかの設定を省略することができ、代わりにやってくれます。あなたのパッケージが com.mycompany.movies というタグをXML(アプリケーションコンテキストファイル)に記述する必要があります。

<context:component-scan base-package="com.mycompany.movies" />

このタグは自動スキャンを行います。ビーンになる必要のある各クラスが、以下のような正しいアノテーションを付けていると仮定します。 @Component (単純なビーンの場合)または @Controller (サーブレットコントロールの場合) または @Repository (の場合)。 DAO クラス) の下にあり、これらのクラスはパッケージのどこか com.mycompany.movies Springはこれらすべてを見つけ、それぞれについてBeanを作成します。これはクラスの2回のスキャンで行われます。1回目はBeanになる必要のあるクラスを検索して、必要な注入をマッピングするだけです。もちろん、より伝統的な XML ファイルでビーンを定義することもできます。 @Configuration クラス(またはその3つの組み合わせ)を使用します。

@Autowired アノテーションは、インジェクションが必要な場所をSpringに伝えます。メソッドにつけると setMovieFinder という接頭辞で理解されます。 set + を追加しました。 @Autowired アノテーション) を使用して、Bean を注入する必要があることを示します。2回目のスキャンで、Springは以下のタイプのBeanを探します。 MovieFinder そして、もしそのようなビーンが見つかったら、このメソッドに注入します。もしそのようなビーンが2つ見つかった場合は Exception . を回避するために Exception を使用することができます。 @Qualifier アノテーションを使用し、次のように 2 つの Bean のうちどちらを注入するかを指示します。

@Qualifier("redBean")
class Red implements Color {
   // Class code here
}

@Qualifier("blueBean")
class Blue implements Color {
   // Class code here
}

また、XMLでビーンズを宣言したい場合は、次のようになります。

<bean id="redBean" class="com.mycompany.movies.Red"/>

<bean id="blueBean" class="com.mycompany.movies.Blue"/>

@Autowired の宣言も必要です。 @Qualifier を使用して、2 つのカラー ビーンのうちどちらを注入するかを指定します。

@Autowired
@Qualifier("redBean")
public void setColor(Color color) {
  this.color = color;
}

もし、2つのアノテーションを使いたくない場合( @Autowired@Qualifier ) を使用することができます。 @Resource を使えば、この2つを組み合わせることができます。

@Resource(name="redBean")
public void setColor(Color color) {
  this.color = color;
}

@Resource (この答えの最初のコメントで、それに関するいくつかの追加データを読むことができます) 2つの注釈の使用を免れ、代わりに、1つだけを使用します。

あと2つだけコメントを追加しておきます。

  1. グッドプラクティスは @Inject の代わりに @Autowired はSpringに特化していないため の部分です。 JSR-330 標準 .
  2. もう一つのグッドプラクティスは @Inject / @Autowired をメソッドではなく、コンストラクタに追加します。コンストラクタに置くと、注入されたBeanがNULLでないことを検証でき、アプリケーションを起動しようとしたときに高速に失敗し、メソッドにエラーが発生するのを避けることができます。 NullPointerException 実際にBeanを使用する必要があるときに

更新 : 絵を完成させるために、私は 新しい質問 についてです。 @Configuration クラスがあります。