关于使用AspectJ的策略实施

时间:2011-04-27 12:21:19

标签: java aop aspectj pointcuts

我正在使用Aspectj进行项目范围的策略实施。

我现在要尝试实现的一件事是,除了使用Guava的Preconditions.check*方法进行简单验证外,任何setter方法都不应该有逻辑。

public pointcut withinSetter() :
    withincode(public void set*(*));
public pointcut inputValidation() :
    call(public void Preconditions.check*(*));
public pointcut setFieldValue() : set(* *);
public pointcut entity() : within(com.mycompany.BaseEntity+);

declare warning :
entity() && withinSetter() && !setFieldValue() && !inputValidation():
"Please don't use Logic in Setters";

这可以按预期工作,为任何非setter代码生成警告。但是,对于这样的结构,它失败了:

public void setFoo(final String newFoo) {
    Preconditions.checkNotNull(newFoo); // this is OK
    Preconditions.checkArgument(
                 newFoo.matches("\\p{Alpha}{3}"), // this generates a warning
                                                  // because String.matches()
                                                  // is called
                "Foo must have exactly 3 characters!");
    this.foo = newFoo;
}

所以我要找的是一个允许任何代码的构造,只要它发生在Preconditions.check*调用的参数内。有没有这样的切入点?

1 个答案:

答案 0 :(得分:1)

我知道这是一个老问题,但我在搜索其他内容时偶然发现了它。

答案是否定的,因为在JVM字节码中没有“check*调用中的逻辑”这样的东西。例如,{<1}}在 之前评估 ,结果传递给newFoo.matches(..),非常类似:

Preconditions.checkArgument(..)

如果代码是这样编写的,那么你会发出一个警告,那么为什么不能将相同的Java代码(可能导致类似或相同的字节代码)写成嵌套调用呢? boolean match = newFoo.matches("\\p{Alpha}{3}"); Preconditions.checkArgument(match, "Foo must have exactly 3 characters!");


更新:我创建了一个小例子:

;-)

如果使用public class Application { public static void main(String[] args) { String newFoo = "Scrum"; boolean match = newFoo.matches("\\p{Alpha}{3}"); checkArgument( match, "Foo must have exactly 3 characters!" ); checkArgument( newFoo.matches("\\p{Alpha}{3}"), "Foo must have exactly 3 characters!" ); } private static void checkArgument(boolean status, String errorMessage) { if (!status) System.out.println(errorMessage); } } 转储字节代码,您会看到:

javap -c Application

如您所见,除了存储和重新加载布尔值之外,转储中第3-13行与第16-24行的字节代码相同。也许这说明了我之前说过的话。