338

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

3.9.2 @Autowired および @Inject

以下の例が理解できません。XML を機能させるには、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 クラスのデザイン メソッドが呼び出されるようにするにはどうすればよいですか?

4

3 に答える 3

577

TL;DR

注釈は@Autowired、XML ファイル (またはその他の方法) で自分でワイヤリングを行う必要をなくし、どこに何を注入する必要があるかを見つけて、それを実行します。

完全な説明

@Autowired注釈を使用すると、注入するものの構成を他の場所でスキップでき、それを行うだけです。パッケージを想定すると、com.mycompany.moviesこのタグを XML (アプリケーション コンテキスト ファイル) に配置する必要があります。

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

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

注釈は、@Autowired注入を行う必要がある場所を Spring に伝えます。メソッドに配置すると、Bean を注入する必要があることがsetMovieFinder(接頭辞set+注釈によって) 理解されます。@Autowired2 回目のスキャンで、Spring は type の 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. これは Spring 固有ではなく、標準の一部である@Injectため、代わりにを使用することをお勧めします。@AutowiredJSR-330
  2. @Inject/@Autowiredをメソッドの代わりにコンストラクターに配置することもお勧めします。コンストラクターに配置すると、注入された Bean が null ではないことを検証でき、アプリケーションを起動しようとするとすぐに失敗し、NullPointerException実際に Bean を使用する必要があるときに a を回避できます。

更新: 全体像を完成させるために、クラスに関する新しい質問を作成しました。@Configuration

于 2013-10-17T06:01:39.930 に答える
5

はい、Spring サーブレット コンテキスト xml ファイルを構成して Bean (つまり、クラス) を定義し、自動注入を行うことができます。ただし、Spring を起動して実行するには他の構成を行う必要があることに注意してください。そのための最善の方法は、チュートリアルの基礎に従うことです。

おそらくSpringを構成したら、上記の例1が機能するようにSpringサーブレットコンテキストxmlファイルで次のことを実行できます(com.movi​​esのパッケージ名を実際のパッケージ名に置き換えてください。これがサードパーティの場合)クラス、適切なjarファイルがクラスパス上にあることを確認してください):

<beans:bean id="movieFinder" class="com.movies.MovieFinder" />

または、 MovieFinder クラスにプリミティブ値を持つコンストラクターがある場合、次のようなことができます。

<beans:bean id="movieFinder" class="com.movies.MovieFinder" >
    <beans:constructor-arg value="100" />
</beans:bean>

または、 MovieFinder クラスに別のクラスを期待するコンストラクターがある場合、次のようなことができます。

<beans:bean id="movieFinder" class="com.movies.MovieFinder" >
    <beans:constructor-arg ref="otherBeanRef" />
</beans:bean>

...ここで、「otherBeanRef」は、予想されるクラスへの参照を持つ別の Bean です。

于 2013-10-17T00:29:00.357 に答える