对象变量赋值方面的aspectj切入点 [英] aspectj pointcuts on object variable assignment

查看:108
本文介绍了对象变量赋值方面的aspectj切入点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无论何时分配变量,我都想在以下示例类上创建切入点.因此,例如,在method1(int number)中,this.x被设置为int.我意识到在这种情况下,我可以在method1上创建一个切入点,然后使用反射找出新的x值是什么.但是,我想知道是否有一种方法可以在this.x = number这行上做一个切入点,以便例如在函数结束之前触发我的切入点?

I would like to create a pointcut on the following sample class whenever a variable gets assigned. So for instance, in method1(int number), this.x gets set to int. I realize in this case I could just make a pointcut on method1 and then find out what the new x value is using reflection. However, I was wondering if there is a way to make a pointcut on the line this.x = number, so that my pointcut gets triggered, for example, before the function ends?

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

推荐答案

您可以使用以下任一方法进行操作:

You can do that with either:

  • 一个特权方面:

  • a privileged aspect:

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

}

  • 使用反射的非特权方面:

  • a non-privileged aspect using reflection:

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

  • 当您需要监视已知类型的已知字段时,建议使用第一个(特权)版本,因为不使用反射会更快.但是,当您需要监视撰写时不知道的字段(例如,用注释标记)或要监视的字段可能有多种类型时,第二个版本可能会派上用场.

    The first (privileged) version is recommended when you need to monitor a known field of a known type, because it's faster by not using reflection. However, when you need to monitor fields which are not known at the time of writing (for instance, marked by an annotation) or there are multiple fields you want to monitor in possibly multiple types, the second version might come handy.

    不是newValueactualNewValue始终应该具有相同的值,但是newValue在更改字段值之前可用,而actualNewValue只能在更改字段值之后获得.

    Not that newValue and actualNewValue should always have the same value, but the newValue is available before changing the field value, while actualNewValue can only be obtained after the field value has been changed.

    这篇关于对象变量赋值方面的aspectj切入点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆