我想从类列表(可能属于不同的包)中记录所有方法的条目。注意,这些方法应该只属于指定的类。
我尝试了以下方法,但这些都不起作用
(1) 在这里使用if()切入点,我得到一个错误
"incompatible number of arguments to pointcut, expected 1 found 0"
@Pointcut("execution(*.*(..)) && if()")
public static boolean mycut(JoinPoint jp) {
boolean matches = ... ;//Test using jp if the declaring class belongs to the list
return matches;
}
(2) 使用切入点和aop的组合。xml在这里我得到一个错误
java.lang.NoSuchMethodError:
com.mypackage.TraceAspect.aspectOf()Lcom/df/jc/aspect/TraceAspect;
//in com.mypackage.TraceAspect aspect class
@Pointcut("execution(*.*(..)) && !within(com.mypackage.TraceAspect)")
public void mycut(){
}
//in aop.xml
<weaver>
<include within="package1.Class1">
<include within="package2.Class2">
<include within="package3.Class3">
</weaver>
这里出了什么问题?
当然可以通过在切入点中单独指定每个类来实现,但这对于数百个类来说是不可扩展的。理想情况下,如果可以从外部文本文件中提取类列表(便于配置),那就太好了
至于你最后的评论:除了糟糕的设计,我并没有阻止你做任何事情,我只是想鼓励你做正确的事情:重构,不要让自己的生活变得比必要的更艰难。您甚至不知道AspectJ语法的基础知识,但您已经想用大量的类实现一个过于复杂的场景,这是一个维护噩梦。我试图通过激励你不要做出短视的决定来帮助你。相信我,我多年来一直在使用AspectJ,在你所说的带有大量遗留代码的现实项目中。即使是最便宜的重构,也要比智能重构昂贵得多——不算太多,但根据童子军规则,这已经足够了:让营地比你发现的更干净。相信我,这是值得的。
无论如何,谈谈你的代码片段:
执行(*.*(...))
在语法上是错误的,因为您没有为要匹配的方法指定返回类型(或占位符)。您想使用执行(**.*(...))
或简写版本执行(**(...))
。@前("myCut()")
的内容,但正确的是@前("myCut(jp)")
。话虽如此,这里有一个简单、完全自包含且可编译的示例:
驱动程序应用:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
System.out.println(multiply(3, add(4, 5)));
}
public static int multiply(int i, int j) { return i * j; }
public static int add(int i, int j) { return i + j; }
}
方面:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class TraceAspect {
@Pointcut("execution(* *(..)) && if()")
public static boolean hasMatchingSignature(JoinPoint thisJoinPoint) {
return !thisJoinPoint.getSignature().getName().equals("main");
}
@Before("hasMatchingSignature(thisJoinPoint)")
public void myAdvice(JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
}
}
样品输出:
execution(int de.scrum_master.app.Application.add(int, int))
execution(int de.scrum_master.app.Application.multiply(int, int))
27
如果您的If()切入点只返回true,那么输出也将显示main的执行。
问题内容: 我有针对特定软件包的此工作代码,但我想针对所有 controllers , service 和 dao 软件包进行配置 com.abc.xyz.content.controller com.abc.xyz.content.service com.abc.xyz.content.dao com.abc.xyz.category.controller com.abc.xyz.categor
问题内容: 我想用指定的注释(例如@Monitor)监视所有类的所有公共方法(注意:注释在类级别)。可能的切入点是什么?注意:我正在使用@AspectJ样式的Spring AOP。 问题答案: 你应该将类型切入点与方法切入点结合使用。 这些切入点将在标记为@Monitor的类中查找所有公共方法: 为结合了前两者的最后一个切入点提供建议,你就完成了!
我正在使用Spring的AspectJ和CGLIB代理。我有一个定义如下的方面,我希望它在具体的类上为公共方法提供建议,这些类是用批注“validatormethod”批注的:
使用加载时间编织,纯AspectJ。 我们有2个注释和,以及一些带注释的方法。 现在我正在为具有多个注释的定义自己的围绕方面: 这行不通。然而,捕获方法myMethod2可以很好地用于单个注释: 我只想捕获签名中同时存在时间和计数注释的方法,并且我想使用注释值。有人知道如何做到这一点吗?
add:如果我将方法存根添加到Fragment2中,就可以开始使用next annotation,但这是一个非常难看的解决方案 解决方案:多亏了@Kriegaex,我找到了解决方案:
服务实现 但是,如果我将注释移动到公共接口方法实现,我的方面就会被触发。我应该如何定义我的切入点或配置我的方面来使我的原始用例工作?