@Transactional
または
@Async
注釈の失敗理由は簡単です。その原則は、プロキシクラスを介して「強化」効果の方法を作ることができるようにメソッドを呼び出すようにすることを意味し、ダイナミックな薬剤です。以下のために、ここで
@Async
の例。
以下の定義は Service
2つの非同期メソッドの実行: test03()
と test02()
時間のかかる操作、その後に発生する可能性がプロジェクトをシミュレートするために使用される test()
メソッドの呼び出し2つの時間のかかる方法を。
定義 Controller
:
結果を返す実行方法:
我々の期待と明らかに矛盾する実行結果の方法は、出力シーケンシャルアプローチは、表現 test02()
と test03()
2つの非同期メソッドは、実際には同期的に実行し、そのがされて @Aysnc
無効注釈付き!
私たちがしているので、失敗の理由がある
test()
、直接呼ばれるプロセスtest02()
およびtest03()
方法と同等、this.test02()
とthis.test03()
実際に呼び出すことを呼び出し、test02()
およびtest03()
方法TestService
ながら、自身が呼び出すオブジェクト@Async
と@Transactional
エージェントの動的な性質を利用して注釈付きは、本当にする必要がありますTestService
プロキシオブジェクトを呼び出す と 方法を。実際には、春のコンテナクラスのオブジェクトは、SpringコンテナがAOPの注釈が含まれているプロキシオブジェクト(理解するために単純なので)「を置き換える」、そしてノートの失敗の理由は、それがオブジェクト自体ではなく、プロキシメソッドの呼び出しであるためであること、非常に明確であるだろうときに初期化何Springコンテナがないため、オブジェクトは、その後、解決策を解決するために、この考え方に沿ったものになります。test02()
test03()
そう確かに非同期注釈不良の問題を解決することができ、多くのオンラインブログは解決策が非同期で個別にクラスに引き込ま実行されると言うがあり、原則は、クラスとして単独で非同期抽出を実行するための方法を入れたときに、このクラスは確かであるということです春が管理されている、あなたは他の春のコンポーネントを呼び出す必要があるとき確かに注入そこに、実際にはそれはプロキシクラス内に注入されるが、実際には他のソリューションがある場合、個別にクラスに描かれている必要はありませんでしょう。
解決策:TestServiceでの非同期メソッドを通じて呼び出しに独自のコンテキストのプロキシオブジェクトを取得します。
実際に、我々は起因して、現在のスプリング部品にSpringコンテナから目標噴射メンバ変数の割り当てである TestService
AOPアノテーションの使用は、実際には TestService
、実際にSpringコンテナ内に存在すると、そのプロキシオブジェクトです。
(リファレンスツールを使用できます
https://blog.csdn.net/Dongguabai/article/details/80788646)
非同期実行非同期メソッドの結果:
道を解く:CGLIBオープンプロキシ、プロキシクラスは手動で春を取得
春のブート起動クラスでプラス:
使用すると、 AopContext.currentProxy()
現在のプロキシクラスを返します:
この主題を実証するためにSpringコンテナには、特別に、出力電流のエージェントクラスオブジェクトの文であります:
結果:
OK、問題の完璧なソリューション!