プロキシクラスは、ターゲットメソッドを呼び出し、プロキシメソッドがそれを実装する方法であるときのブログ記事では、我々は残りの部分に主に、プロキシクラスを生成するには、このいずれかを話しました、私たちはその後、パートにReflectiveMethodInvocationクラスのメソッドを進んで見て
パブリックオブジェクトを進める()がスローされたThrowable { //はまず、判決は、すべてのインターセプタ(もAdvisorを考えることができますが)オーバーが実行されているではありません。 // 決意の方法は、この変数currentInterceptorIndexの値を確認することで、値の総数は、インターセプタれない増加 // それが到着した場合、それが実行されるプロキシ方式(invokeJoinpoint());そうでない場合、実行はインターセプタが続きます。 IF(この .currentInterceptorIndexは== この .interceptorsAndDynamicMethodMatchers.sizeを() - 1 ){ 戻りinvokeJoinpointを(); } // インターセプタは完全に完全に実装されていない場合は、実行するインターセプタを取られ、そして実行されました。 // currentInterceptorIndex第自己増力 オブジェクトinterceptorOrInterceptionAdviceを= この .interceptorsAndDynamicMethodMatchers.get(++ 本.currentInterceptorIndex); // インターセプタは、ポイントカットタイプであれば IF(interceptorOrInterceptionAdvice のinstanceof InterceptorAndDynamicMethodMatcher)は{ DM InterceptorAndDynamicMethodMatcher = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice; // 現在の制限方法は、ポイントカットインターセプタ、実装インターセプタを準拠している場合 IF(dm.methodMatcher.matches(この .method、この .targetClass、この.arguments)){ // ここで、このとき変数が渡され、これは非常に重要なポイントである リターン dm.interceptor.invoke(この); } // 現在のインターセプタがスキップされない場合、次のインターセプタを行う 他{ 戻る)(進みます。 } } // インターセプタインターセプタ強化ない場合はポイントカットタイプ、直接実行内部。 他{ リターン((MethodInterceptorの)interceptorOrInterceptionAdvice).invoke(この)。 } }
のは、メソッド呼び出しのシーケンス図を見てみましょう
我々は、我々はインターセプタAspectJAfterThrowingAdviceのメソッドを呼び出す見て取り、これらのインターセプタを順に実行され、チェーンの順序はAspectJAfterThrowingAdvice、AfterReturningAdviceInterceptor、AspectJAfterAdvice、MethodBeforeAdviceInterceptorで見ます
AspectJAfterThrowingAdvice
1つの @Override 2 パブリックオブジェクトを呼び出し(MethodInvocation MI)はスローのThrowable { 3 のtry { 4 // の直接MethodInvocationと呼ばれる進行方法 5 // 我々は(これを)dm.interceptor.invoke知る進む()メソッドのパラメータ上を通過することをReflectiveMethodInvocation自体は、アクチュエータ 6は、 // ここで再び、直接法)(ReflectiveMethodInvocationが進行呼び出し 7。 リターンmi.proceedを() 。8 } 。9 キャッチ(ThrowableのEX){ 10 IF (shouldInvokeOnThrowing(EX)){ 11。 invokeAdviceMethod(getJoinPointMatch() 、NULL 、EX)。 12 } 13 投EX。 14 } 15 }
AspectJAfterThrowingAdviceメソッドを呼び出す最初のインターセプター、直接呼び出しmi.proceed();我々が知っているdm.interceptor.invoke進む()メソッドからは、(これは)ReflectiveMethodInvocationアクチュエータ自体は、それが実行するパラメータ上を通過します、スタックの第7行の最初のインターセプタのinvoke()メソッドこの場合,,()メソッドは、インターセプタ添字currentInterceptorIndex増分、次インターセプタAfterReturningAdviceInterceptorを取得進行、およびメソッド呼び出しインターセプターを呼び出します次に我々は、第二のインターセプタの実装を見て
AfterReturningAdviceInterceptor
1 @Override 2 パブリックオブジェクトを呼び出し(MethodInvocation MI)はスローのThrowableを{ 3 // 直接调用MethodInvocation的進行方法 4 オブジェクトRETVAL = mi.proceed()。 5 本.advice.afterReturning(RETVAL、mi.getMethod()、mi.getArguments()、mi.getThis())。 6 リターンRETVAL。 7 }
AfterReturningAdviceInterceptor直接()mi.proceedを呼び出し、当時進行()メソッドは、4行目の今回AfterReturningAdviceInterceptorカードにおける方法、進行()メソッドは、インターセプタ添字currentInterceptorIndex増分のReflectiveMethodInvocationに戻すのにReflectiveMethodInvocation次の迎撃AspectJAfterAdviceを取得し、そしてAspectJAfterAdviceのinvokeメソッドを呼び出します
AspectJAfterAdvice
1 @Override 2 パブリックオブジェクトを呼び出し(MethodInvocation MI)はスローのThrowable { 3 のtry { 4 // 直接调用MethodInvocation的方法進行 5 リターンmi.proceedを(); 6 } 7 最後に{ 8 invokeAdviceMethod(getJoinPointMatch()、NULL、NULL ); 9 } 10 }
バック進む()メソッドは、場合のReflectiveMethodInvocationにAspectJAfterAdviceまたは直接()mi.proceedを呼び出し、AspectJAfterAdviceの次に、5行目のメソッドカードは、進行()メソッドは、インターセプタ添字currentInterceptorIndex増分、取得ReflectiveMethodInvocationに返さ次の迎撃MethodBeforeAdviceInterceptor、およびMethodBeforeAdviceInterceptorのinvokeメソッドを呼び出します
MethodBeforeAdviceInterceptor
1 @Override 2 パブリックオブジェクトを呼び出し(miザMethodInvocation)がスローされたThrowable { 3 // 最後に、メソッド呼び出しエンハンサーの前に、有意呼び出しによって反射され、物事を開始 4 // 方法本明細書で前に拡張ビジネス・ロジックを実行する 。5 本.advice.before(mi.getMethod()、mi.getArguments()、mi.getThis()); 6 // および呼び出しメソッド呼び出しを進行MethodInvocation 。7 戻りmi.proceed(); 8 }
最後にメソッドを呼び出す前に、内部のカットを反映させることにより、コードの第5行、その後、彼らは(mi.proceedを呼び出す)、我々はこれが最後のインターセプタで知って、そして今回this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1これが真である必要があり、それはリターンinvokeJoinpoint()を実行します;、それは豆を実行するためのターゲット方法であり、その後、我々はターゲットメソッドの実装を見て
@Nullable 保護オブジェクトinvokeJoinpoint()はスローのThrowableを{ 戻り AopUtils.invokeJoinpointUsingReflection(この .TARGET、この .method、この.arguments)を、 } @Nullable パブリック 静的オブジェクトinvokeJoinpointUsingReflection(@Nullableオブジェクトターゲットメソッド方法、オブジェクト[]引数)が スローのThrowableを{ // メソッドを呼び出すためにリフレクションを使用してください。 してみてください{ ReflectionUtils.makeAccessible(方法) // 直接ターゲットBeanメソッドの反射によって呼び出さ リターンMethod.invoke(ターゲット、引数)。 } キャッチ(InvocationTargetExceptionがexは){ // 呼び出されたメソッドがチェック例外をスローしました。 // 我々はそれを再スローしなければなりません。クライアントは、インターセプタは表示されません。 スローex.getTargetExceptionを(); } キャッチ(例外:IllegalArgumentExceptionの例){ スロー 新しい( "AOPの設定が無効のようです:メソッドを呼び出してみました[" +のAopInvocationExceptionの 方法 "ターゲット上+] [" +対象+ "]" 、EX); } キャッチ(例外:IllegalAccessExceptionの例){ スロー 新しい AopInvocationExceptionを( "メソッドにアクセスできませんでした[" +方法+ "]" 、EX); } }
後者の方法を実施する前に、反射の仕方によって方法でターゲットBeanの実装に、その結果を返します、そして、我々はそれを強制するプログラム方法はないでしょうか?
、スタックが後退し始めたMethodBeforeAdviceInterceptorが完成し実行した後1、AspectJAfterAdviceカード)は、5行目のコードは、我々は最終的にはこの文でinvokeAdviceMethod(getJoinPointMatch(でメソッドを呼び出すAspectJAfterAdvice最初の8で見たラインの下続けて呼び出します、)、ヌルNULL;、最後にので、いずれにせよ実行される@Afterカットクラスのメソッドを意味AfterAdviceを呼び出す方法で反射され
図2は、AspectJAfterAdviceはinvokeメソッドの実装後に発行され、invokeメソッドのライン上に、次いで脱積層し始め、4 AfterReturningAdviceInterceptorが回復し始めたが、対象は豆とブースタ異常の前に表示された場合、第1 AfterReturningAdviceInterceptorコードの5行は、実行直接脱積層されません。例外が発生しない場合、ライン5が実行され、方法は、注釈@AfterReturningアスペクトクラスを反映することによって行われ、その後、脱積層します
3、AfterReturningAdviceInterceptor AspectJAfterThrowingAdviceインターセプタへデ積み重ね、このインターセプタ線7 invokeメソッドは、回復を開始し、我々は、キャッチ(ThrowableをEX){コード、即ち、ライン11 invokeAdviceMethod(getJoinPointMatch()を、参照しますヌル、EX)、またはBean異常の前に標的を高める方法がある場合、それはここでキャッチでキャッチされ、方法は、注釈を付け方法を@AfterThrowing反射によって行われ、その後、脱積層
概要
プロキシクラスは、プロセスを呼び出し、我々はReflectiveMethodInvocationクラスによってプロセスへの再帰呼び出しを再帰呼び出し、オーダー実行インターセプタチェーンAspectJAfterThrowingAdvice、AfterReturningAdviceInterceptor、AspectJAfterAdvice、MethodBeforeAdviceInterceptorこれらのインターセプタを進んでいることがわかります、迎撃に反映コール強化