Aspectj は Spring Framework のすべてのイベントをキャッチしませんか?

StackOverflow https://stackoverflow.com/questions/39639

  •  09-06-2019
  •  | 
  •  

質問

私のプロジェクトは Spring Framework 2.5.4 に基づいています。そして、いくつかのコントローラーにアスペクトを追加してみます(私はaspectj 1.5.3を使用しています)。

application-servlet.xml で自動プロキシを有効にし、次の行を XML ファイルの最後に貼り付けました。

<aop:aspectj-autoproxy />
<bean id="auditLogProcessor" class="com.example.bg.web.utils.AuditLogProcessor" />

作成されたアスペクト:

package com.example.bg.web.utils;

import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AuditLogProcessor
{
    private final static Logger log = Logger.getLogger(AuditLogProcessor.class);

    @After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
    public void afterHandleRequest() {
        log.info("test111");
    }

    @After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
    public void afterRebuildThumbnail() {
        log.info("test222");
    }
}

私のコントローラー:

class AssetAddController implements Controller
class AssetThumbnailRebuildController extends MultiActionController

アスペクトアドバイザーにブレーキポイントを設定し、コントローラーを呼び出したとき、私はhandlerequest()の後にのみキャッチしますが、andrebildthumbnail()は何を間違えましたか?

注記

SO ベータ版にアクセスできない友人に代わってこの質問をしていますが、それが何なのかまったくわかりません。

編集

確かにいくつかのスペルミスがありました、Cheekysoft に感謝します。しかし、問題は依然として残っています。

役に立ちましたか?

解決

Spring の AOP プロキシを使用しているため、ブレークポイントはヒットしません。見る AOP プロキシの理解 AOP プロキシがどのように特別であるかについては、「AOP プロキシの特殊性」を参照してください。

基本的に、MVC フレームワークは handleRequest コントローラーのプロキシ上のメソッド (たとえば、 MultiActionController 基本クラスの実装として使用している)、このメソッドは、rebuildThumbnail メソッドへの「内部」呼び出しを行いますが、これはプロキシを経由しないため、いかなる側面も取得しません。(これはメソッドが最終的なものであることとは何の関係もありません。)

望むものを達成するには、ロード時間ウィービング (Spring はこれを非常にうまくサポートしています) を介して「実際の」 AOP を使用することを検討してください。

他のヒント

AspectJ は、Spring Web MVC フレームワークのクラスではうまく機能しません。 ページの右側にある [拡張機能を開く...] ボックスの下部を読んでください。

代わりに、以下を見てください。 ハンドラーインターセプター インターフェース。

新しい Spring MVC アノテーションは、コントローラー クラスがすべて POJO であるため、同様に機能する可能性がありますが、私自身は試していません。

基本的なセットアップは問題ないようです。

インプレースポイントカットを定義せず、アフターアドバイスを適用するメソッドを指定するだけで、構文を若干簡素化できます。(メソッドの名前付きポイントカットは自動的に作成されます。)

例えば

@After( "com.example.bg.web.controllers.assets.AssetAddController.handleRequest()" )
public void afterHandleRequest() {
    log.info( "test111" );
}

@After( "com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail()" )   
public void afterRebuildThumbnail() {
    log.info( "test222" );
}

ただし、rebuildThumbnail メソッドが最終的なものではなく、メソッド名とクラスが正しい場合に限ります。なぜこれがうまくいかないのかわかりません。

見る http://static.springframework.org/spring/docs/2.0.x/reference/aop.html

これはスペルと同じくらい簡単ですか?それとも質問に単なるタイプミスがあるのでしょうか?時々あなたは書きます rebuildThumbnail そして時々あなたは書きます rebildThumbnail

アドバイスでオーバーライドしようとしているメソッドは、MVCフレームワークの最終メソッドではないため、bpapasの回答は役に立ちますが、この場合はこれが問題ではないことが私の理解です。ただし、次のことを確認してください。 rebuildThumbnail コントローラーのアクションは最終的なものではありません

@bパパス:私が間違っていたら訂正してください。プログラマ自身のコントローラ アクションは、プログラマがオーバーライドしようとしているものです。MultiActionController ソース (およびその親) を見ると、スタック内にある可能性がある唯一の最終化されたメソッドは次のとおりです。 MultiActionController.invokeNamedMethod, ただし、その時点でこれがスタックにあるかどうかは 100% わかりません。スタックの上位にファイナライズされたメソッドがあると、さらに下位のメソッドに AOP アドバイスを追加するときに問題が発生しますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top