私はJava config with _@ComponentScan
_ inを使用して、Beanと@EnableAspectJAutoProxy(proxyTargetClass=true)
を初期化してcglibプロキシを使用しています。
このプロジェクトでは、_@Autowired
_を使用して生成された多くのサービスがそれらの間で自動接続されています。かなりうまくいきます。
しかし、これらのサービスの一部については、_@Async
_を追加しました(_@Configuration
_ classにも@EnableAsync(proxyTargetClass = true)
を追加しました)。
その後、私は得ています:
_Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'ConversationUserLocalService': Bean with name 'ConversationUserLocalService' has been injected into other beans [ConversationUserHistoryLocalService] i
n its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'a
llowEagerInit' flag turned off, for example.
_
これは、AOPがプロキシを作成する前に、Springが_@Async
_ methodでサービスを注入しているためだと思います。これが問題なのでしょうか?どうすれば修正できますか?
私の問題を明確にするために、私が持っているとしましょう:
@サービスA、B、C
Aに自動配線されたBおよびC Bに自動配線されたAおよびC Cに自動配線されたAおよびBがある
Cには@Asyncとしてマークされたメソッドがあります。
SpringがapplicationContextを初期化するとき、Aを初期化しようとしますが、BとCが必要なので、それらを初期化します。しかし、結局のところ、AOPは(@Asyncが原因で)Cのプロキシを作成しようとし、BとAに自動配線されたCがCのプロキシと同じではないことを検出し、失敗します。
これで何が起こっているかをもう少し説明できるといいのですが。
AsyncConfigurer構成クラスは、アプリケーションコンテキストブートストラップの初期段階で初期化されます。そこで他のBeanに依存関係が必要な場合は、それらを他のポストプロセッサも通過させるために、可能な限り「遅延」と宣言するようにしてください。
最後に、@Lazy
onサービス(@Async
アノテーションが付いたメソッド)、およびを使用して、自動配線された場所で分類しました。このように、Springは、アプリケーションコンテキストの初期化ではなく、必要な場合にのみそれらのサービスを初期化し、自動配線します。
@Autowireと一緒に@Qualifierを追加することで、同様の問題を修正することができました。例えば:
@Autowired
@Qualifier("publisher")
private Publisher publisher;