Spring インジェクションが@Bean
アノテーション付きのメソッド呼び出しをどのように処理するか興味があります。@Bean
メソッドにアノテーションを付けてインスタンスを返す場合、メソッドを呼び出して返されたインスタンスを取得することで Bean を作成するように Spring に指示することは理解しています。ただし、その Bean は他の Bean を接続したり、他のコードを設定したりするために使用する必要があります。通常、これを行うには、@Bean
アノテーション付きのメソッドを呼び出してインスタンスを取得します。私の質問は、なぜこれによって Bean の複数のインスタンスが浮遊しないのかということです。
たとえば、以下のコードを参照してください (別の質問から引用)。entryPoint()
メソッドには の注釈が付いているため、spring は の新しいインスタンスをBean として@Bean
作成すると考えられます。次に、 configure ブロックで を再度呼び出しますが、 はBean インスタンスを返し、複数回呼び出されないようです (ログに記録しようとしましたが、ログ エントリは 1 つしか取得されませんでした)。構成の他の部分で を複数回呼び出す可能性があり、常に同じインスタンスが取得されます。私の理解は正しいでしょうか。spring は の注釈が付けられたメソッドを魔法のように書き換えるのでしょうか。BasicAuthenticationEntryPoint
entryPoint()
entryPoint()
entryPoint()
@Bean
@Bean
public BasicAuthenticationEntryPoint entryPoint() {
BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint();
basicAuthEntryPoint.setRealmName("My Realm");
return basicAuthEntryPoint;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(entryPoint())
.and()
.authorizeUrls()
.anyRequest().authenticated()
.and()
.httpBasic();
}
ベストアンサー1
はい、春は魔法チェックしてくださいSpring ドキュメント:
ここで魔法が起こります。すべての
@Configuration
クラスは起動時にサブクラス化され、CGLIBサブクラスでは、子メソッドは、親メソッドを呼び出して新しいインスタンスを作成する前に、まずコンテナ内でキャッシュされた (スコープ指定された) Bean をチェックします。
@Bean
これは、メソッドの呼び出しがCGLIBしたがって、Bean のキャッシュされたバージョンが返されます (新しいものは作成されません)。
@Bean
sのデフォルトのスコープは ですSINGLETON
が、 などの異なるスコープを指定した場合、PROTOTYPE
呼び出しは元のメソッドに渡されます。
これは静的メソッドには無効ですSpring のドキュメントによると:
静的メソッドの呼び出しは、技術的な制限により、
@Bean
コンテナによってインターセプトされることはありません。クラス内であっても(このセクションで前述したように)、CGLIB のサブクラス化では非静的メソッドのみをオーバーライドできます。その結果、別のメソッドへの直接呼び出しには標準の Java セマンティクスが適用され、独立したインスタンスがファクトリ メソッド自体から直接返されます。@Configuration
@Bean