关于使用 AspectJ 执行策略
我正在使用 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*
调用的参数内即可。有这样的切入点吗?
I am using Aspectj for project-wide policy enforcement.
One thing I am trying to implement now is that there should be no logic in any setter methods except simple validation with Guava's Preconditions.check*
methods.
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";
This works as expected, generating warnings for any non-setter code. However, it fails for constructs like this:
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;
}
So what I am looking for is a construct that would allow any code, as long as it happens inside the parameters to a Preconditions.check*
call. Is there such a pointcut?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我知道这是一个老问题,但我只是在搜索其他内容时偶然发现了它。
答案是否定的,因为在 JVM 字节码中不存在“
检查中的逻辑”之类的东西*
调用”。例如,在将结果传递给Preconditions.checkArgument(..)< 之前评估
newFoo.matches(..)
/code>,非常像这样:如果代码是这样编写的,那么您无论如何都会发出警告,那么为什么不将相同的 Java 代码(可能导致相似或相同的字节代码)编写为嵌套调用呢?
;-)
更新: 我创建了一个小例子:
如果您使用
javap -c Application
转储字节代码,您会看到:可以看到,转储中第 3-13 行和第 16-24 行的字节码是相同的,除了布尔值的存储和重新加载之外。也许这说明了我之前所说的。
I know it is an old question, but I just stumbled across it while searching for something else.
The answer is no, because in JVM bytecode there is no such thing as "logic inside a
check*
call". For example,newFoo.matches(..)
is evaluated before the result is passed toPreconditions.checkArgument(..)
, very much like this:If the code was written like this, you would issue a warning anway, so why not if the same Java code, possibly resulting in similar or identical byte code, is written as a nested call?
;-)
Update: I have created a little example:
If you dump the byte code using
javap -c Application
you see this:As you can see, the byte code of lines 3-13 versus 16-24 in the dump is identical except for the storing and re-loading of the boolean value. Maybe this illustrates what I have said before.