web-dev-qa-db-ja.com

Springで@Beanアノテーション付きメソッドを呼び出すJava configuration

_@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();       
}
_
75
markwatson

はい、Springはいくつかのmagicを実行します。 Spring Docs を確認してください:

これが魔法の出番です。すべての@Configurationクラスは、起動時に [〜#〜] cglib [〜#〜] でサブクラス化されます。サブクラスでは、子メソッドは親メソッドを呼び出して新しいインスタンスを作成する前に、キャッシュされた(スコープされた)Beanのコンテナを最初にチェックします。

これは、@Beanメソッドの呼び出しが [〜#〜] cglib [〜#〜] を介してプロキシされ、したがってBeanのキャッシュバージョンが返されることを意味します(新しいものは作成されません) )。

@BeansのデフォルトのスコープはSINGLETONです。PROTOTYPEなどの別のスコープを指定すると、呼び出しは元のメソッドに渡されます。

これは、静的メソッドには無効であることに注意してください。春のドキュメントによると:

静的な@Beanメソッドの呼び出しは、技術的な制限により、コンテナによってインターセプトされることはなく、@Configurationクラス内でもインターセプトされません(このセクションで前述)。結果として、別の@Beanメソッドへの直接呼び出しには、標準のJavaセマンティクスがあり、ファクトリメソッド自体から独立したインスタンスが直接返されます。

101
wassgren