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


98

スプリングインジェクションが@Beanアノテーション付きの呼び出しメソッドをどのように処理するかについて知りたいです。私が入れた場合は@Bean、インスタンスのメソッドに注釈を、と戻り、私はそれがメソッドを呼び出して、返されたインスタンスを取得することにより、Beanを作成するために、春を告げることを理解しています。ただし、他のBeanを接続したり、他のコードを設定したりするために、そのBeanを使用する必要がある場合があります。これを行う通常の方法は、@Bean注釈付きメソッドを呼び出してインスタンスを取得することです。私の質問は、なぜこれが原因でBeanの複数のインスタンスが浮かんでいないのですか?

たとえば、次のコード(別の質問からの抜粋)を参照してください。このentryPoint()メソッドにはの注釈が付けられている@Beanので、Springがの新しいインスタンスをBasicAuthenticationEntryPointBeanとして作成すると想像します。次に、entryPoint()configureブロックで再度呼び出しentryPoint()ますが、Beanインスタンスを返しているようで、何度も呼び出されていません(ロギングを試みましたが、ログエントリが1つしかありませんでした)。entryPoint()構成の他の部分で複数回呼び出す可能性があり、常に同じインスタンスを取得します。これに対する私の理解は正しいですか?Springは、アノテーションが付けられたメソッドの魔法のような書き直しを行い@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();       
}

回答:


130

はい、春は魔法をかけます。春のドキュメントを確認してください:

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

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

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

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

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


この方法で作成されたBeanをオーバーライドすることは可能ですか?たとえば、Bean作成メソッドを直接呼び出すSpring定義クラスがあります。私が欲しいのは、そのメソッドによって作成されていないBeanが使用されていることですが、私は(とそれに注釈を付けることで自分自身を定義する1つ@Bean@Primary)。
Fons

4
しかし、プロキシ(jdkまたはCGLIBのいずれか)が自己呼び出しでは機能しないことも思い出します。@ ConfigurationはどのようにBean間の依存関係を定義するのでしょうか。それは正確に自己呼び出しを使用します
Nowhy 2018年

3
@Nowhy CGLib allows us to create proxy classes at runtime by creating sub class of specified class using Byte code generation. CGLib proxies are used in the case where Proxy is to be created for those class which does not have any interfaces or have methods which are not declared in the implementing interface. この場合、CGLIBは@Configurationクラスのサブクラスを作成し、そのメソッド(@Beanメソッドを含む)をオーバーライドします。したがって、@ Beanメソッドを別のメソッドから呼び出す場合、実際にはオーバーライドされたバージョンを呼び出します(Java動的バインディングのおかげです)。
Flame239 2018

したがって@Component、Java Poxyの代わりにCHLIBを使用してプロキシを作成した場合、selfInvocation AOPは機能しますか?
Antoniossss
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.