0

@Aspect別の側面のポイントカットによってインターセプトされるメソッドを宣言する があります。アスペクトはコンパイル時のウィービングで作成され、コンテナーは Spring を使用してインスタンス化されます。

@Configurableコンポーネントがコンテナーの外部で作成されていることを Spring に伝えるために、アスペクトに で注釈を付けました。この側面でも、たまたまLogオブジェクトへの静的参照があります。要約すると、コードは次のようになります

@Aspect
@Configurable
public class MyAspect {
    private static final Log log = LogFactory.getClass(MyAspect.class);
    // Autowired dependencies

    // Pointcuts and advice

    // Happens to be a pointcut of some other Advice
    @Asynchronous
    private Object someMethod(...) {
    }
}

AspectJ のコンパイル中に、次のようなメッセージが表示されません。

weaveinfo Join point 'method-call(java.lang.Object mypackage.someMethod(...))' in Type 'mypackage.MyAspect' (MyAspect.java:30) advised by around advice from 'anotherpackage.AsynchronousAspect' (from AsynchronousAspect.java))

予想どおり、この時点でサードパーティのアドバイスが呼び出されることはありません。ただし、アドバイスに簡単なログ エントリを追加すると、

log.debug("Join point invoked!");

次に、コンパイルが正しく行われ、すべての側面が配線され (サードパーティの依存関係を含む)、正しく呼び出されます。

ログ エントリを追加すると、想定が変更されますか?

4

1 に答える 1

0

自分が何をしているのかを知っていれば、やりたいことは非常に簡単で、まったく危険ではありません。私は Spring ユーザーではなく、@AspectJ よりもネイティブの AspectJ 構文を好むことをお詫び申し上げます。この小さなサンプルは問題なく動作します。

public class Application {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        someMethod();
    }

    private static void someMethod() {
        System.out.println("Doing something ...");
    }
}
public aspect FirstAspect {
    void around() : execution(void *..main(..)) {
        System.out.println(thisJoinPointStaticPart + ": " + someMethod("before", "main"));
        proceed();
        System.out.println(thisJoinPointStaticPart + ": " + someMethod("after", "main"));
    }

    private Object someMethod(String position, String methodName) {
        return position + " " + methodName;
    }
}
public aspect SecondAspect {
    Object around() : execution(* *..someMethod(..)) {
        System.out.println(thisJoinPointStaticPart + ": before someMethod");
        Object result = proceed();
        System.out.println(thisJoinPointStaticPart + ": after someMethod");
        return result;
    }
}

結果は期待どおりです。

execution(Object FirstAspect.someMethod(String, String)): before someMethod
execution(Object FirstAspect.someMethod(String, String)): after someMethod
execution(void Application.main(String[])): before main
Hello world!
execution(void Application.someMethod()): before someMethod
Doing something ...
execution(void Application.someMethod()): after someMethod
execution(Object FirstAspect.someMethod(String, String)): before someMethod
execution(Object FirstAspect.someMethod(String, String)): after someMethod
execution(void Application.main(String[])): after main

さらに、アスペクトが適用/実行される順序が気になる場合は、 を使用してくださいdeclare precedence

プライベート メンバーなどへのアクセスで問題が発生した場合は、privileged aspect.

更新:の使用法を に変更thisEnclosingJoinPointStaticPartしましたthisJoinPointStaticPart。単なるコピペミスでした。結果はexecution結合点で同じですが、いずれにせよ修正はコードの意図をよりよく示しています。

于 2013-03-15T13:03:11.260 に答える