2016-10-29 9 views
0

변수가 할당 될 때마다 다음 샘플 클래스에서 pointcut을 만들고 싶습니다. 예를 들어 method1 (int number)에서 this.x는 int로 설정됩니다. 이 경우에는 method1에 포인트 컷을 만든 다음 새로운 x 값이 리플렉션을 사용하여 무엇인지 알아낼 수 있습니다. 그러나 this.x = number에 pointcut를 만드는 방법이 있는지 궁금 해서요. 예를 들어 함수가 끝나기 전에 내 pointcut이 실행되도록할까요?aspectj 객체 변수 지정에 대한 pointcuts

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); 
         } 
        } 
    
    } 
    

알려진 유형의 알려진 필드를 모니터링해야 할 때 첫 번째 (권한있는) 버전이 좋습니다. 리플렉션을 사용하지 않는 것이 더 빠르기 때문입니다. 그러나 작성시 알려지지 않은 필드 (예 : 주석으로 표시됨)를 모니터링해야하거나 여러 유형으로 모니터링하려는 필드가 여러 개인 경우 두 번째 버전이 유용 할 수 있습니다.

는 그 newValueactualNewValue 항상 같은 값을해야하지,하지만 필드 값을 변경 한 후 actualNewValue 만 얻을 수있는 동안 newValue은 필드 값을 변경하기 전에 사용할 수 있습니다.