Spring @Autowired の使い方を理解する 質問する

Spring @Autowired の使い方を理解する 質問する

Spring Autowired アノテーションを理解するために、Spring 3.0.x リファレンス ドキュメントを読んでいます。

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 クラスのデザイン メソッドが呼び出されるようにするにはどうすればよいですか?

ベストアンサー1

要約

アノテーション@Autowiredを使用すると、XML ファイル (またはその他の方法) で自分で配線する必要がなくなり、どこに何を注入する必要があるかが自動的に検出され、自動的に実行されます。

詳しい説明

アノテーション@Autowiredを使用すると、他の場所で何を注入するかの設定をスキップして、自動的に実行できます。パッケージが次のとおりであると仮定すると、com.mycompany.moviesXML (アプリケーション コンテキスト ファイル) に次のタグを配置する必要があります。

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

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

アノテーション@Autowiredは、注入を行う必要がある場所を Spring に伝えます。メソッドにアノテーションを付けると、setMovieFinder(プレフィックスset+@Autowiredアノテーションによって) Bean を注入する必要があることが理解されます。2 回目のスキャンでは、Spring は タイプの Bean を検索しMovieFinder、そのような Bean が見つかった場合は、このメソッドに注入します。そのような Bean が 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 を宣言する場合は、次のようになります。

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

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

宣言では、 を追加して、2 つのカラー Bean のどちらを注入するかを指定する@Autowired必要があります。@Qualifier

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

@Autowired2 つの注釈 (と@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もう 1 つの良い方法は、 / をメソッドではなくコンストラクターに配置することです@Autowired。コンストラクターに配置すると、注入された Bean が null でないことを検証でき、アプリケーションを起動しようとしたときにすぐに失敗し、NullPointerException実際に Bean を使用する必要があるときにエラーを回避できます。

更新:絵を完成させるために、新しい質問クラスについて@Configuration

おすすめ記事