クラスパススキャンを使用してxml Beanの定義を取り除くために、@Component
アノテーションがSpring 2.5で導入されたことを私は理解しています。
@Bean
はspring 3.0で導入され、xmlファイルを完全に取り除き代わりにJava configを使うために@Configuration
と一緒に使うことができます。
@Component
アノテーションを導入する代わりに@Bean
アノテーションを再利用することは可能でしたか?私の理解するところでは、最終的な目標はどちらの場合もBeanを作成することです。
@Component
と@Bean
はまったく異なる2つのことをしているので混同しないでください。
@Component
(および@Service
と@Repository
)は、クラスパススキャンを使用してBeanを自動検出および自動設定するために使用されます。注釈付きクラスとBeanの間には暗黙的な1対1のマッピングがあります(つまり、クラスごとに1つのBean)。これは純粋に宣言型なので、配線の制御はこのアプローチではかなり制限されます。
@Bean
は、上記のようにSpringに自動的に行わせるのではなく、明示的に単一のBeanを宣言するために使用されます。それはBeanの宣言をクラス定義から切り離し、あなたが選択したとおりにBeanを作成し設定することを可能にします。
あなたの質問に答えるには.
@Component
アノテーションを導入する代わりに@Bean
アノテーションを再利用することは可能でしたか?
もちろんです。しかし、彼らはそうしないことを選びました、それは2つが全く違うからです。春はもう水面を混乱させずに十分に混乱します。
@Component コンポーネントのスキャンや自動配線に適しています。
いつ @Bean を使うべきですか?
自動設定が選択肢にならないことがあります。 いつ? サードパーティのライブラリからコンポーネントをワイヤリングしたい(あなたはソースコードを持っていないので@Componentでそのクラスにアノテーションを付けることができない)ので、自動設定は不可能です。
@Bean annotation はSpringをアプリケーションコンテキストでbeanとして登録すべきオブジェクト を返します。 メソッドの本体 はインスタンスの作成を担当するロジックを担います。
動的状態に応じて具体的な実装が欲しいと考えてみましょう。 @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
でそれをする方法はありません。
どちらのアプローチも、Springコンテナにターゲットタイプを登録することを目的としています。
違いは、@Bean
はメソッドに適用可能であるのに対し、@Component
は型に適用可能であることです。
したがって、@Bean
アノテーションを使用すると、メソッド本体のインスタンス作成ロジックを制御できます(上記の の例 を参照)。 @Component
アノテーションではできません。
@ 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の実際の目的と使用法について明確なアイデアが得られたと思います。アノテーション.
@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));
}
Beanを生成する方法は2つあります。一つはアノテーション@Component
を持つクラスを作成することです。もう1つは、メソッドを作成し、それに@Bean
というアノテーションを付けることです。 @Bean
のメソッドを含むクラスは@Configuration
のアノテーションを付ける必要があります。Springプロジェクトを実行すると、@ComponentScan
アノテーションのあるクラスはすべてのクラスを@Component
でスキャンし、このクラスのインスタンスをIocコンテナに復元します。 @ComponentScan
が行うもう1つのことは、@Bean
を付けてメソッドを実行し、returnオブジェクトをBeanとしてIocコンテナに復元することです。したがって、現在の状態に応じてどの種類のBeanを作成するかを決定する必要がある場合は、@Bean
を使用する必要があります。ロジックを書いて欲しいオブジェクトを返すことができます。もう1つ言及する価値があるのは、@Bean
を持つメソッドの名前がBeanのデフォルト名です。
- @Controller パブリッククラスLoginController {--code--} - @Configuration パブリッククラスAppConfig { @Bean public SessionFactory sessionFactory() {--code--}
@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によって自動的に処理されます。
@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をインスタンス化して使用するためのすべての構成手順を回避するために導入されたばかりです。