5

私は実行時にクラスをロードし、この時点でいくつかのAspectJアスペクトでそれらを織り込もうとしています。ロードタイムウィービングを有効にしましたが、従来の方法で使用すると機能します。

@Aspectクラスには次のものがあります。

@Before("call(* mypackage.MyInterface.*())")
public void myInterfaceExecuteCall(JoinPoint thisJoinPoint,
        JoinPoint.StaticPart thisJoinPointStaticPart,
        JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart) {
    System.out.println(thisJoinPoint.getSignature().getDeclaringType());
    System.out.println(thisJoinPoint.getSignature().getName());
}

次に、jarをスキャンして、次の実装であるクラスを見つけていますMyInterface

URLClassLoader classLoader = new URLClassLoader(new URL[] { urlOfJar },
        ClassLoader.getSystemClassLoader());
WeavingURLClassLoader weaver = new WeavingURLClassLoader(
        classLoader);
HashSet<Class<?>> executableClasses = new HashSet<Class<?>>();
for (String name : classNamesInJar) {
    try {
        Class<?> myImplementation = weaver.loadClass(name);
        if (MyInterface.class.isAssignableFrom(myImplementation)) {
            executableClasses.add(myImplementation);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } catch (NoClassDefFoundError e) {
        e.printStackTrace();
    }
}

...そして、ある時点で、ロードされたクラスで特定のメソッドを実行しています。

try {
    Method execute = myImplementation.getMethod("execute");
    execute.invoke(myImplementation.newInstance());
} catch (Exception e) {
    e.printStackTrace();
}

ただし、上記で示した@Beforeメソッドは、呼び出したときに実行されることはありませんexecute.invoke(...)(ただし、executeメソッド自体は明らかに実行されますが、その出力が表示されます)。

誰かが私が間違っていることを知っていますか?myInterfaceExecuteCallロードされたクラスのメソッドが呼び出される前にgetを呼び出す方法は何ですか?

4

2 に答える 2

6

OK、それが何であるかはわかりましたが、意図したとおりには機能しませんが、回避策は次のとおりです。

@Before("execution(* mypackage.MyInterface.*())")の代わりにa を実行するだけですcall。これは、クラスがカスタム クラス ローダーによって実行時に手動でロードされた場合でも機能します。これは、AspectJ が using で行われた呼び出しを気にしないためMethod.invoke(...)です。他の誰かがこの回避策を使用できることを願っています。

記憶に残る情報を含むドキュメントへのリンクは次のとおりです。

たとえば、pointcut 呼び出しは、java.lang.reflect.Method.invoke(Object, Object[]) で実装されたメソッドへのリフレクション呼び出しを選択しません。

http://www.eclipse.org/aspectj/doc/released/progguide/implementation.html

別の解決策がある場合は、遠慮なくご回答ください。

于 2012-05-24T16:18:47.960 に答える
0

私が間違っていなければ、AspectJ は JDK クラスを織り込むことができません。それはこれを説明します:

たとえば、pointcut 呼び出しは、java.lang.reflect.Method.invoke(Object, Object[]) で実装されたメソッドへのリフレクション呼び出しを選択しません。

于 2013-06-26T14:45:18.477 に答える