概要
前の記事では、Beanに自分自身を注入した場合、@Asyncと@Transactionがある場合、@Autowireに自分自身を注入すると、円形の依存関係を報告することが紹介されています。 BeanFactoryAwareを注入すると、 @Transactionが無効になります。例えば:
@ServicePublic Class MyServiceはBeanFactoryAware {private myService self; //トランザクションアノテーションは無効です@transactional public void notwork(){...} @async public future async(){...} @override public void setbeanfactory(beanfactory beanfactory)beansexception {self = beanfactory.getbean(myservice.class); }}当時簡単に言及しましたが、この記事はそれが失敗した理由を紹介することです。
一般的な
上記の状況では、次の条件を満たす必要があります。
結果は次のとおりです。@asyncを除き、下の図に示すように、注釈が有効になり、他のものが有効になりません。
通常のプロキシは次の図でなければなりません。
理由
最初に思い浮かぶのは、@Asyncアノテーションの処理方法が他のものとは異なる可能性があるということです。 AsyncannotationBeanPostProcessor(特定のコードは親クラスの抽象化beanpostprocessorにある)の実装では、問題が見つかりました、
通常の状況では、入ってくるBeanはすでにプロキシされている動的なプロキシクラスであり、失敗した場合、実際のクラスは、以下の図に示すようにです。
次に、コードを分析した後、それが実際のクラスの場合、それが69行目に達すると、それは真実に戻り、 @aysNCのアドバイザーを動的原理に追加します。実際のクラスの場合、83行目に到達すると、プロキシクラスが作成され、 @aysNCのアドバイザーがダイナミックプロキシに追加するだけなので、すでに @Transactionが無効になります。
エージェントが入ってこないのはなぜですか?
実際、唯一の違いは、BeanFactoryAwareを通じて自分自身を獲得したかどうかです。それでは、なぜBeanFactoryを使用して自分を手に入れるのに、その後のBeanPostProcessorの代理ではないのですか? Spring @Transactionロードメカニズムに精通している場合は、@Transactionや@retryable Annotationsなどの動的プロキシ作成がAnnotationAwareaspectjautoproxycreatorで作成されていることがわかります。 Debugを通じて、AnnotationAwareaspectjautoproxycreatorを通過した後、私たちの動的なプロキシが追加されていないことがわかりました。
AnnotationAwareaspectjautoproxycreatorの実装を見てみましょうが、その後、プロキシクラスは生成されませんでした。その理由は、事前に露出したマップに「myService」があるためです。
彼はいつ暴露されましたか?実はそうです
@OverridePublic void setBeanFactory(BeanFactory BeanFactory)Throws BeanSexception {self = beanfactory.getBean(myservice.class);}その後、すべてが明らかになりました。 MyServiceでは、BeanFactoryAwareがトリガーされ、BeanFactory.getBean(myservice.class)を介してプロキシクラスが作成されました。 (ヒント:現在のプロキシクラスには @AsyncのAdivisorが含まれていません)。Springは実際にMyService Beanを作成しており、まだBeanFactoryに入れられていないからです。次に、BeanFactory.getBean(myservice.class)をトリガーしました。このプロセスでは、プロキシを作成して返し、事前に露出したマップに参加しました。これは、その後の一連の問題につながります。少しもつれを感じます。写真に話しかける:
通常、次のプロセスは次のとおりです。
これは異常な状況の場合です
まとめ
通常の状況では、 @autowireを使用して注入します(Autowireが使用されている場合、上記の状況は円形の依存関係を直接投げます)。もちろん、問題がある場合は、手放すことはできません。あなたは理由と理由を知っている必要があります!
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。