web-dev-qa-db-ja.com

春:@Componentと@Bean

クラスパススキャンを使用してxml Beanの定義を取り除くために、@ComponentアノテーションがSpring 2.5で導入されたことを私は理解しています。

@Beanはspring 3.0で導入され、xmlファイルを完全に取り除き代わりにJava configを使うために@Configurationと一緒に使うことができます。

@Componentアノテーションを導入する代わりに@Beanアノテーションを再利用することは可能でしたか?私の理解するところでは、最終的な目標はどちらの場合もBeanを作成することです。

327
user1396576

@Component@Beanはまったく異なる2つのことをしているので混同しないでください。

@Component(および@Service@Repository)は、クラスパススキャンを使用してBeanを自動検出および自動設定するために使用されます。注釈付きクラスとBeanの間には暗黙的な1対1のマッピングがあります(つまり、クラスごとに1つのBean)。これは純粋に宣言型なので、配線の制御はこのアプローチではかなり制限されます。

@Beanは、上記のようにSpringに自動的に行わせるのではなく、明示的に単一のBeanを宣言するために使用されます。それはBeanの宣言をクラス定義から切り離し、あなたが選択したとおりにBeanを作成し設定することを可能にします。

あなたの質問に答えるには.

@Componentアノテーションを導入する代わりに@Beanアノテーションを再利用することは可能でしたか?

もちろんです。しかし、彼らはそうしないことを選びました、それは2つが全く違うからです。春はもう水面を混乱させずに十分に混乱します。

338
skaffman

@Component コンポーネントのスキャンや自動配線に適しています。

いつ @Bean を使うべきですか?

自動設定が選択肢にならないことがあります。 いつ? サードパーティのライブラリからコンポーネントをワイヤリングしたい(あなたはソースコードを持っていないので@Componentでそのクラスにアノテーションを付けることができない)ので、自動設定は不可能です。

@Bean annotation はSpringをアプリケーションコンテキストでbeanとして登録すべきオブジェクト を返します。 メソッドの本体 はインスタンスの作成を担当するロジックを担います。

261
MagGGG

動的状態に応じて具体的な実装が欲しいと考えてみましょう。 @Beanはその場合に最適です。

@Bean
@Scope("prototype")
public SomeService someService() {
    switch (state) {
    case 1:
        return new Impl1();
    case 2:
        return new Impl2();
    case 3:
        return new Impl3();
    default:
        return new Impl();
    }
}

しかし@Componentでそれをする方法はありません。

148
outdev

どちらのアプローチも、Springコンテナにターゲットタイプを登録することを目的としています。

違いは、@Beanメソッドに適用可能であるのに対し、@Componentに適用可能であることです。

したがって、@Beanアノテーションを使用すると、メソッド本体のインスタンス作成ロジックを制御できます(上記の の例 を参照)。 @Componentアノテーションではできません。

66
Nurlan
  1. @Component auto detectはクラスパススキャンを使用してBeanを設定しますが、@ Bean 明示的に宣言はSpringに自動的に実行させるのではなく、単一のBeanに設定します。
  2. @Component デカップリングしないクラス定義からのBeanの宣言ここで@Bean デカップリングクラス定義からのBeanの宣言.
  3. @Componentはクラスレベルのアノテーションです。@Beanはメソッドレベルのアノテーションであり、メソッドの名前はBeanの名前となります。
  4. @Component @Configurationと共に使用する必要はありません annotationここで@Beanアノテーションは@Configurationでアノテーションが付けられたクラス内で使用されるである必要があります。
  5. クラスがSpringコンテナの外にある場合は@Componentを使用するクラスのWe Beanを作成できません _が存在する場合でも@Beanを使用するクラスのWe Beanは作成できませんスプリングコンテナの外側
  6. @Component、@ Repository、および@Serviceのように@Componentはさまざまな特殊化を持ちますが、@Beanは特殊化なしを持ちます。
47
Saurabh Prakash

@ Componentこれは汎用アノテーションであり、アプリケーションの任意のクラスに適用して、それをSpring管理対象コンポーネントにすることができます(単にSpring管理対象コンポーネントの汎用ステレオタイプ)。クラスパスがspringのcomponent-scan(@ ComponentScan)機能によってスキャンされると、@ Componentのアノテーションが付けられたクラスが識別されます。 (指定されたパッケージ内で)アノテーションを付け、そのようなクラスのBeanを作成してApplicationContextに登録します。 @ Componentはクラスレベルのアノテーションで、その目的はクラスパス検索機能のためのSpring管理コンポーネントおよび自動検出Beanとしてクラスを作成することです。

@ Componentや他のステレオタイプアノテーションについてもっと知りたいのなら、この記事を見て することをお勧めします .

@ Beanは、メソッドから返されるSpring IOCコンテナーにBeanを(構成Beanとして)明示的に宣言して登録するために使用されます。 @Beanはメソッドレベルのアノテーションで、@ Configurationのアノテーションが付けられたクラス内で使用されます。簡単に言えば、@ Beanアノテーションは、メソッドによって返されたBeanをSpringコンフィグレーションBeanとしてIOC Containerに登録するために使用されます。 @ Beanはメソッドレベルの注釈にすぎず、クラスやオブジェクトの宣言では使用できません。

@ Beanアノテーションは、メソッドがSpringコンテナによって管理されるBeanを生成することを示します。

Beanを宣言するには、単に@ Beanアノテーションでメソッドにアノテーションを付けます。 JavaConfigがそのようなメソッドに遭遇すると、そのメソッドを実行し、戻り値をApplicationContext内のBeanとして登録します。デフォルトでは、Bean名はメソッド名と同じになります。以下は@Beanメソッド宣言の簡単な例です。

@Configuration
public class ApplicationConfig {

    @Bean
    public User adminUserProfile() {
        return new User("Rami","Nassar");
    }
}

ApplicationConfigクラスでは、最初に@ Configurationアノテーションを使用して、これがJavaベースの構成ファイルであることをSpringに通知しています。その後、@ Beanアノテーションを使用してSpring BeanとDI要件を宣言します。 @ Beanアノテーションはタグと同等であり、メソッド名はタグ内のid属性と同等です。この記事を読んだ後で、@ Bean@ Componentの実際の目的と使用法について明確なアイデアが得られたと思います。アノテーション.

37
Rami Nassar

@Componentタグを使用する場合、それはバニラビーン宣言メソッド(@Beanでアノテーションが付けられた)を持つPOJO(Plain Old Java Object)を持つことと同じです。たとえば、次の方法1と2は同じ結果になります。

方法1

@Component
public class SomeClass {

    private int number;

    public SomeClass(Integer theNumber){
        this.number = theNumber.intValue();
    }

    public int getNumber(){
        return this.number;
    }
}

「theNumber」のBeanを使用します。

@Bean
Integer theNumber(){
    return new Integer(3456);
}

方法2

//Note: no @Component tag
public class SomeClass {

    private int number;

    public SomeClass(Integer theNumber){
        this.number = theNumber.intValue();
    }

    public int getNumber(){
        return this.number;
    }
}

両方の豆と一緒に:

@Bean
Integer theNumber(){
    return new Integer(3456);
}

@Bean
SomeClass someClass(Integer theNumber){
    return new SomeClass(theNumber);
}

方法2では、Beanの宣言をまとめて保持することができます。これは、もう少し柔軟です。以下のような、Vanilla SomeClass以外の他のBeanを追加したい場合もあります。

@Bean
SomeClass strawberryClass(){
    return new SomeClass(new Integer(1));
}
13
SomeGuy

Beanを生成する方法は2つあります。一つはアノテーション@Componentを持つクラスを作成することです。もう1つは、メソッドを作成し、それに@Beanというアノテーションを付けることです。 @Beanのメソッドを含むクラスは@Configurationのアノテーションを付ける必要があります。Springプロジェクトを実行すると、@ComponentScanアノテーションのあるクラスはすべてのクラスを@Componentでスキャンし、このクラスのインスタンスをIocコンテナに復元します。 @ComponentScanが行うもう1つのことは、@Beanを付けてメソッドを実行し、returnオブジェクトをBeanとしてIocコンテナに復元することです。したがって、現在の状態に応じてどの種類のBeanを作成するかを決定する必要がある場合は、@Beanを使用する必要があります。ロジックを書いて欲しいオブジェクトを返すことができます。もう1つ言及する価値があるのは、@Beanを持つメソッドの名前がBeanのデフォルト名です。

4
Dai Niu
  • @componentとその特殊化(@Controller、@ service、@ repository)により、クラスパススキャンを使用した自動検出が可能になります。 @Controller、@ serviceなどのコンポーネントクラスが表示された場合、@リポジトリはコンポーネントスキャンを使用してSpringフレームワークによって自動的にスキャンされます。
  • 一方@Beanは、設定クラスで単一のBeanを明示的に宣言するためにのみ使用できます。
  • @Beanは、Springに自動的に行わせるのではなく、単一のBeanを明示的に宣言するのに使用されていました。そのmakeはクラス定義からbeanの宣言を分離します。
  • つまり、@ Controller、@ service、@ repositoryは自動検出用で、@ Beanはクラスから別のBeanを作成するためのものです。
  -  @Controller 
パブリッククラスLoginController 
 {--code--} 
 
  -  @Configuration 
パブリッククラスAppConfig { 
 @Bean 
 public SessionFactory sessionFactory()
 {--code--} 
4
alok

@Beanを使用して、既存のサードパーティクラスをSpringフレームワークアプリケーションコンテキストで使用可能にすることができます。

@Bean
public ViewResolver viewResolver() {

    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

    viewResolver.setPrefix("/WEB-INF/view/");
    viewResolver.setSuffix(".jsp");

    return viewResolver;
}

@Beanアノテーションを使用すると、サードパーティクラス(@Componentがなく、Springを使用しない場合があります)をSpring Beanとしてラップできます。そして、@Beanを使用してラップされると、シングルトンオブジェクトとして、Springフレームワークアプリケーションコンテキストで使用可能になります。依存性注入と@Autowiredを使用して、アプリでこのBeanを簡単に共有/再利用できます。

@Beanアノテーションは、サードパーティクラスのラッパー/アダプターであると考えてください。 Springフレームワークアプリケーションコンテキストでサードパーティクラスを使用できるようにします。

上記のコードで@Beanを使用することで、メソッド内でnewキーワードを使用してオブジェクトを明示的に作成しているため、単一のBeanを明示的に宣言しています。また、指定されたクラスのセッターメソッドを手動で呼び出しています。そのため、プレフィックスフィールドの値を変更できます。したがって、この手作業は明示的な作成と呼ばれます。同じクラスに@Componentを使用すると、Springコンテナに登録されたBeanのプレフィックスフィールドにデフォルト値が設定されます。

一方、クラスに@Componentアノテーションを付ける場合、newキーワードを手動で使用する必要はありません。 Springによって自動的に処理されます。

3
elvis

@Beanは、コンパイル時にSpringとビジネスルールを結びつけないようにするために作成されました。つまり、PlayFrameworkやJEEなどの他のフレームワークでビジネスルールを再利用できるということです。

さらに、Beanの作成方法を完全に制御できます。デフォルトのSpringインスタントでは不十分です。

私はそれについて話している記事を書いた。

https://coderstower.com/2019/04/23/factory-methods-decoupling-ioc-container-abstraction/

私はたくさんの答えを見ていますし、その@Componentはコンポーネントがスキャンされる自動配線用で、@ Beansは正確に宣言されています。その違いを見せてください。

  • @豆

まずメソッドレベルのアノテーションです。次に、一般にJavaコードでBeanを設定し(xml設定を使用していない場合)、ApplicationContextのgetBeanメソッドを使用してクラスから呼び出します。好き

 @Configuration
class MyConfiguration{
    @Bean
    public User getUser(){
        return new User();
    }
}

class User{
}



//Getting Bean 
User user = applicationContext.getBean("getUser");
  • @成分

これは、特殊なBeanではなく、Beanに注釈を付けるための一般的な方法です。クラスレベルのアノテーションで、Javaやxmlの設定を通じて、そのような設定をすべて回避するために使用されます。

私たちはこのようなものを手に入れました。

@Component
class User {
}

//to get Bean
@Autowired
User user;

それでおしまい 。このBeanをインスタンス化して使用するためのすべての構成手順を回避するために導入されたばかりです。

2
xpioneer