問題を分析する一つのことを理解する必要があります。ExposeInvocationInterceptor
1.公式から以下の情報を得ます:
AspectJのを使用した場合、スプリングはコネクタチェーンのアドバイスの先頭に追加され、知ることができます。しかし、なぜこの事は何に置きますか?それは、それをしているのですか?
ソースコードを見て2:
** * 現在{@link org.aopalliance.intercept.MethodInvocation}公開さインターセプタ スレッドローカルオブジェクトとして*を。私たちは、時折する必要が行う 、これを。以下のためにたとえば、ときポイントカット * (例えばAspectJの発現ポイントカット)は、完全な呼び出しコンテキストを知る必要があります。 * * <P>これは本当に必要でない限り、このインターセプターを使用しないでください。ターゲット・オブジェクトは、必要がある として*通常、春AOPについて知っているではない、これは春のAPIへの依存を作成します。 * ターゲットオブジェクトは、可能な限りプレーンのPOJOでなければなりません。 * * <P>使用している場合、このインターセプタは通常、インターセプタチェーンの最初になります。 * * @authorロッドジョンソン * @authorユルゲンHoeller * / @SuppressWarnings( "シリアル" ) パブリック クラス ExposeInvocationInterceptorは実装MethodInterceptorの、PriorityOrdered、シリアライズ{ / ** このクラスのシングルトンインスタンス* / パブリック 静的 最終 ExposeInvocationInterceptor INSTANCE = 新しい)ExposeInvocationInterceptorを( ; / ** *このクラスのシングルトン顧問。使用しているときINSTANCEに優先して使用します *春AOP、それはインスタンスをラップする新しい顧問を作成する必要がなくなりますよう。 * / パブリック 静的 最終アドバイザアドバイザ= 新しいDefaultPointcutAdvisor(インスタンス){ @Override パブリック文字列のtoString(){ 戻り ExposeInvocationInterceptorを。クラス .getName()+ "ADVISOR。" ; } }。 プライベート 静的 最終的にThreadLocal <MethodInvocation>呼び出し= 新しい NamedThreadLocal <MethodInvocation>( "現在のAOPのメソッド呼び出し" ); / ** *現在の呼び出しに関連付けられているAOPアライアンスMethodInvocationオブジェクトを返します。 * @return呼出しオブジェクト現在の呼び出しに関連付けられた * @throws 進行中のAOPの呼び出しがない場合は、IllegalStateException *またはExposeInvocationInterceptorこのインターセプタチェーンに追加されなかった場合 * / パブリック 静的 MethodInvocation currentInvocation()はスローIllegalStateExceptionが{ MethodInvocation MI = invocation.get (); もし(MI == nullの)//错误就是下面抛出来的 (新しいIllegalStateExceptionがスロー "いいえMethodInvocationが見つかりました:AOPの呼び出しが進行中であることを確認し、その" + 「ExposeInvocationInterceptorは、インターセプタチェーンで先行で具体的には、ことに注意してください。」+ )「注文HIGHEST_PRECEDENCEとのアドバイスがExposeInvocationInterceptor前に実行されます!」; 返すマイルを。 } / ** *唯一の正規のインスタンスを作成することができるようにします。 * / プライベートExposeInvocationInterceptor(){ } @Override パブリックオブジェクトを呼び出し(MethodInvocation MI)はスローのThrowableを{ MethodInvocation oldInvocation = invocation.get()。 invocation.set(MI);実際にこのインターセプタの役割を見ては//あなたが簡単にスレッド変数MethodInvacationで子スレッドを得ることができるので、スレッドMethodInvacationにThreadLocal変数を置くことです 試し{ 返すマイルを。 )(進む; } 最後に{ invocation.set(oldInvocation); } } @Override 公共 のint getOrder(){ PriorityOrdered.HIGHEST_PRECEDENCE +を返す1。; //それは本当にチェーンの先頭インターセプトするために配置された場所を知ることができます } / ** *シリアル化をサポートするために必要では。Canonicalのインスタンスに置き換え Singletonパターンを保護する、直列化復元ON *。 * <P>上書きに代替{ @codeは方法等しい}を。 * / プライベートreadResolve(){オブジェクト を返すインスタンス。 } }
説明は、おそらく、このような(純粋Google翻訳)の源である、上記参照してください。
現在の露光* {@link org.aopalliance.intercept.MethodInvocation}インターセプター *スレッドとローカルオブジェクト。時折、我々はそうする必要があります。例えば、出発点のとき (例えば、AspectJの表現ポイントカット)*は、コールの完全なコンテキストを知っておく必要があります。 * * 絶対に必要な場合を除き、このインターセプタを使用しないでください。ターゲット・オブジェクトは、必要があり 、それは春のAPIへの依存関係を作成しますので、*、しばしば春AOPのに気づいていません。 *対象読者は、通常のようにPOJOでなければなりません。 * *使用している場合、これは通常、チェーンを傍受する最初のインターセプターです。
上記の理解を通じて、私たちは基本的に知っているExposeInvocationInterceptorこのインターセプタがされ、それをやって、なぜ必要がありますインターセプタチェーンの先頭に置くと、それがどのようにチェーンの最初に傍受されるのを。しかし、少しはこれらの点を混同している:たまにZeyangはそれを行うようなものがありますか?コールコンテキストはZeyang曲ですか?
3.ルック栗(ソースはソースを示している:https://codeday.me/bug/20190410/930090.htmlを、著者の投稿のおかげで):
一般的に、我々はこのために、次のいます:
@Around(...) パブリックオブジェクトモニター(ProceedingJoinPoint PJP)がスローされたThrowable { // いくつかのコードを OBJのO = pjp.proceed()。 // 何らかのコード }
次に、以下のコードのこの種が存在します。
プライベート 静的 ExecutorServiceのエグゼ= Executors.newCachedThreadPool(); @Around(...) パブリックオブジェクトモニター(ProceedingJoinPointのPJP)がスローされたThrowable { オブジェクトOBJ = ヌル。 呼び出し可能な <OBJECT>タスク= 新しい呼び出し可能な<OBJECT> (){ パブリックオブジェクト呼び出し(){ 戻りpjp.proceed()。 } }。 将来の<Object>未来= executor.submit(タスク)。 試す{ OBJ = future.get(タイムアウト、TimeUnit.MILLISECONDS)。 } キャッチ(TimeoutExceptionの元){ ... } キャッチ(InterruptedExceptionある電子){ // 私たちはこれを無視し... } キャッチ(ExecutionException電子){ スロー)(e.getCauseを。// 呼び出されたメソッドによって発生した例外再スロー } 最後に{ future.cancel(真)// よいか、この望まないかもしれ } 戻りOBJを、 }
コードは、第二の問題を変更する必要があるしたら:
MethodInvocationが見つかりません:AOPの呼び出しが進行中であることを確認し、ExposeInvocationInterceptorがインターセプタチェーンで先行されています。最上位とアドバイス具体的には、ノート
4.アクセスソリューション
MethodInvocationを取得するためのリード。以上のことから、今大体の問題は、このインターセプタを進める()を実行するために、すなわちExposeInvocationInterceptor前に、)(pjp.proceedにある知っています。これは、傍受につながるチェーンの先頭には保証のExposeInvocationInterceptorではありません、これだけの戦略の合計が春のソースに問題がないことであることを保証するために、現在のソリューションは、@Orderインターセプタによる注文の履行を確保することである、と述べました