2016-10-29 11 views
0

変数が割り当てられるたびに、次のサンプルクラスでポイントカットを作成したいと思います。たとえば、method1(int number)では、this.xはintに設定されます。私はこの場合、method1でポイントカットを作成してから、新しいx値がリフレクションを使っていることを知ることができます。しかし、関数thisが終わる前に、私のpointcutがトリガされるように、this.x = numberという行にポイントカットを作成する方法があるかどうか疑問に思っていましたか?aspectjオブジェクト変数代入のポイントカット

あなたがいずれかでそれを行うことができ
public class Sample { 
private int x; 

public void method1(int number) { 
    this.x = number; 
} 

public int getX() { 
    return this.x; 
} 

public void method1(int number, String value) { 
    this.x = number; 
} 

public void method2(String value) { 
    this.x = 105; 
} 
} 
+0

特定のコード行にポイントカットを設定することはできません。メソッド上でのみ。 – Heri

答えて

1

  • 特権側面:

    import java.lang.reflect.Field; 
    import org.aspectj.lang.reflect.FieldSignature; 
    
    public privileged aspect FieldChangeMonitorAspect { 
    
        void around(Sample sample): set(int Sample.x) && target(sample) { 
         FieldSignature fieldSignature = (FieldSignature) thisJoinPoint.getSignature(); 
         Field field = fieldSignature.getField(); 
    
         int oldValue = sample.x; 
         int newValue = ((Integer)thisJoinPoint.getArgs()[0]).intValue(); 
         proceed(sample); 
         int actualNewValue = sample.x; 
    
         System.out.printf("changed field %s: old value=%d, new value=%d, " 
           + "actual new value=%d\n", 
           field, oldValue, newValue, actualNewValue); 
        } 
    
    } 
    
  • 反射を利用して非特権側面:

    import java.lang.reflect.Field; 
    import org.aspectj.lang.reflect.FieldSignature; 
    
    public aspect FieldChangeMonitorAspectWithReflection { 
    
        void around(Sample sample): set(int Sample.x) && target(sample) { 
         FieldSignature fieldSignature = (FieldSignature) thisJoinPoint.getSignature(); 
         Field field = fieldSignature.getField(); 
         try { 
          Object oldValue = field.getInt(sample); 
          Object newValue = thisJoinPoint.getArgs()[0]; 
          proceed(sample); 
          Object actualNewValue = field.get(sample); 
    
          System.out.printf("changed field %s: old value=%d, new value=%d, " 
            + "actual new value=%d\n", 
            field, oldValue, newValue, actualNewValue); 
         } catch (IllegalArgumentException | IllegalAccessException e) { 
          throw new RuntimeException(e); 
         } 
        } 
    
    } 
    

既知のタイプの既知のフィールドを監視する必要がある場合は、リフレクションを使用しないほうが高速ですので、最初の(特権)バージョンをお勧めします。しかし、書いている時点で知られていないフィールド(例えば、注釈でマークされているフィールド)を監視する必要がある場合や、複数のタイプで監視したいフィールドが複数ある場合は、2番目のバージョンが便利です。 newValueactualNewValueは常に同じ値を持つ必要がありますが、フィールドの値が変更された後actualNewValueしか得ることができながらnewValueは、フィールドの値を変更する前に利用可能であることを

ありません。

関連する問題