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
中包含的逻辑封装到另一个类中,它会更干净。我倾向于将方面视为入口点,仅此而已,允许您将实际逻辑打包到一个更可重用的组件中。这样你就不需要处理这个问题了。我知道这个问题很老了,但仍然被列为未回答的问题。如果我的回答合适的话,请你接受并投赞成票好吗?谢谢