在一个方面声明一个方面

时间:2013-03-11 22:51:57

标签: java aspectj

我碰巧有一个@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!");

然后编译正确进行,并且所有方面都是有线的(包括我的第三方依赖项)并正确调用。

添加日志条目会改变我的假设吗?

1 个答案:

答案 0 :(得分: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加入点的结果相同,但无论如何,更正都会更好地显示代码的意图。