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());
}

然后我正在扫描罐子并找到实现的类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

好的,我发现了它是什么,它并没有按照我的预期工作,但这里有一个解决方法:

只是做一个@Before("execution(* mypackage.MyInterface.*())")而不是call。即使该类是由自定义类加载器在运行时手动加载的,这仍然有效。这是因为 AspectJ 不关心使用 using 完成的调用Method.invoke(...)。我希望其他人可以使用此解决方法。

这是包含令人难忘信息的文档的链接:

例如,调用切入点不会挑选出对 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 类。这可以解释这一点:

例如,调用切入点不会挑选出对 java.lang.reflect.Method.invoke(Object, Object[]) 中实现的方法的反射调用。

于 2013-06-26T14:45:18.477 回答