AspectJによる政策施行について
質問
プロジェクト全体のポリシー施行にAspectJを使用しています。
私が今実装しようとしていることの1つは、Guavaの単純な検証を除いて、セッターメソッドにロジックがないはずであるということです。 Preconditions.check*
方法。
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";
これは、予想通りに機能し、セッター以外のコードの警告を生成します。ただし、このような構成要素では失敗します。
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*
電話。そのようなポイントカットはありますか?
解決
私はそれが古い質問であることを知っていますが、私は何か他のものを探している間、ちょうどそれにつまずきました。
JVM bytecodeには「内部のロジックのようなものがないため、答えはいいえです。 check*
call "。たとえば、 newFoo.matches(..)
評価されます 前 結果はに渡されます Preconditions.checkArgument(..)
, 、このようなもの:
boolean match = newFoo.matches("\\p{Alpha}{3}");
Preconditions.checkArgument(match, "Foo must have exactly 3 characters!");
コードがこのように書かれている場合、あなたは警告を繰り返します。そのため、同じJavaコードが類似または同一のバイトコードをもたらす可能性がある場合、ネストされた呼び出しとして書かれているのはなぜですか? ;-)
アップデート: ちょっとした例を作成しました:
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
あなたはこれを見る:
Compiled from "Application.java"
public class Application extends java.lang.Object{
public Application();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16; //String Scrum
2: astore_1
3: aload_1
4: ldc #18; //String \p{Alpha}{3}
6: invokevirtual #20; //Method java/lang/String.matches:(Ljava/lang/String;)Z
9: istore_2
10: iload_2
11: ldc #26; //String Foo must have exactly 3 characters!
13: invokestatic #28; //Method checkArgument:(ZLjava/lang/String;)V
16: aload_1
17: ldc #18; //String \p{Alpha}{3}
19: invokevirtual #20; //Method java/lang/String.matches:(Ljava/lang/String;)Z
22: ldc #26; //String Foo must have exactly 3 characters!
24: invokestatic #28; //Method checkArgument:(ZLjava/lang/String;)V
27: return
}
ご覧のとおり、ダンプの16〜24行目のバイトコードは、ブール値の保存と再荷重を除き、同一です。たぶんこれは私が前に言ったことを示しています。
所属していません StackOverflow