_@Bean
_アノテーションを使用して、スプリングインジェクションがメソッドの呼び出しをどのように処理するかについて興味があります。メソッドに_@Bean
_注釈を付けてインスタンスを返すと、メソッドを呼び出して返されたインスタンスを取得することで、SpringがBeanを作成するように指示することがわかります。ただし、そのBeanを使用して、他のBeanを配線したり、他のコードを設定したりする必要がある場合があります。これを行う通常の方法は、_@Bean
_アノテーション付きメソッドを呼び出してインスタンスを取得することです。私の質問は、なぜこれが豆の複数のインスタンスが浮かんでいる原因にならないのですか?
たとえば、次のコードを参照してください(別の質問から引用)。 entryPoint()
メソッドには_@Bean
_アノテーションが付けられているため、SpringはBasicAuthenticationEntryPoint
の新しいインスタンスをBeanとして作成すると思います。次に、configureブロックでentryPoint()
を再度呼び出しますが、entryPoint()
はBeanインスタンスを返し、複数回呼び出されないようです(ロギングを試行し、ログを1つだけ取得しました)エントリ)。潜在的に、構成の他の部分で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();
}
_
はい、Springはいくつかのmagicを実行します。 Spring Docs を確認してください:
これが魔法の出番です。すべての
@Configuration
クラスは、起動時に [〜#〜] cglib [〜#〜] でサブクラス化されます。サブクラスでは、子メソッドは親メソッドを呼び出して新しいインスタンスを作成する前に、キャッシュされた(スコープされた)Beanのコンテナを最初にチェックします。
これは、@Bean
メソッドの呼び出しが [〜#〜] cglib [〜#〜] を介してプロキシされ、したがってBeanのキャッシュバージョンが返されることを意味します(新しいものは作成されません) )。
@Bean
sのデフォルトのスコープはSINGLETON
です。PROTOTYPE
などの別のスコープを指定すると、呼び出しは元のメソッドに渡されます。
これは、静的メソッドには無効であることに注意してください。春のドキュメントによると:
静的な
@Bean
メソッドの呼び出しは、技術的な制限により、コンテナによってインターセプトされることはなく、@Configuration
クラス内でもインターセプトされません(このセクションで前述)。結果として、別の@Bean
メソッドへの直接呼び出しには、標準のJavaセマンティクスがあり、ファクトリメソッド自体から独立したインスタンスが直接返されます。