Java 在方面上声明方面

Java 在方面上声明方面,java,aspectj,Java,Aspectj,我碰巧有一个@Aspect,它声明了一个被另一个Aspect的切入点截获的方法。方面是通过编译时编织创建的,容器是使用Spring实例化的 我用@Configurable注释了我的方面,告诉Spring组件是在容器外部创建的。在这方面,我碰巧也有一个对Log对象的静态引用。总而言之,代码如下所示 @Aspect @Configurable public class MyAspect { private static final Log log = LogFactory.getClass(

我碰巧有一个
@Aspect
,它声明了一个被另一个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!");
然后正确地进行编译,所有方面都连接(包括我的第三方依赖项)并正确地调用


添加日志条目的作用是什么来改变我的假设?

如果您知道自己在做什么,那么您想要做的事情非常简单,一点也不危险。请原谅我不是Spring用户,我更喜欢原生AspectJ语法而不是@AspectJ。这个小示例运行良好:

公共类应用程序{
公共静态void main(字符串[]args){
System.out.println(“你好,世界!”);
somethod();
}
私有静态方法(){
System.out.println(“做某事…”);
}
}
公共方面第一方面{
void around():执行(void*.main(..){
System.out.println(thisJoinPointStaticPart+“:”+someMethod(“before”,“main”));
继续();
System.out.println(thisJoinPointStaticPart+“:”+someMethod(“之后”、“主”));
}
私有对象someMethod(字符串位置、字符串方法名称){
返回位置+“”+methodName;
}
}
公共方面第二方面{
对象环绕():执行(**…someMethod(..){
System.out.println(thisJoinPointStaticPart+“:在someMethod之前”);
对象结果=继续();
System.out.println(thisJoinPointStaticPart+“:在someMethod之后”);
返回结果;
}
}
结果如预期:

执行(Object FirstAspect.someMethod(String,String)):在someMethod之前 执行(Object FirstAspect.someMethod(String,String)):在someMethod之后 执行(void Application.main(String[]):在main之前 你好,世界! 执行(void Application.someMethod()):在someMethod之前 做点什么。。。 执行(void Application.someMethod()):在someMethod之后 执行(Object FirstAspect.someMethod(String,String)):在someMethod之前 执行(Object FirstAspect.someMethod(String,String)):在someMethod之后 执行(void Application.main(String[]):在main之后 如果您还关心应用/执行方面的顺序,请使用
声明优先级

如果您在访问私人成员等方面遇到问题,则需要使用
特权特性


更新:
ThisEnclosuringJoinPointStaticPart
的用法更改为
thisJoinPointStaticPart
。这只是一个复制粘贴错误。在
执行
连接点上的结果是相同的,但无论如何,更正显示了代码的更好意图。

我不知道这种设计。我喜欢方面,但如果你坚持这个方向,我会担心过于复杂。我可以看到一年后有人挠头说“他们在想什么?”难道没有更简单的方法吗?这可能没有听起来那么糟糕,如果你从整体上看这个系统,这可能更有意义,为什么我要走这条路:)这两个建议完全无关。碰巧我依赖于一个使用aspectj的库,而我的aspect依赖于这个库的功能。对我来说,如果您将
MyAspect
中包含的逻辑封装到另一个类中,它会更干净。我倾向于将方面视为入口点,仅此而已,允许您将实际逻辑打包到一个更可重用的组件中。这样你就不需要处理这个问题了。我知道这个问题很老了,但仍然被列为未回答的问题。如果我的回答合适的话,请你接受并投赞成票好吗?谢谢