Spring AOP - 在调用 setter 之前获取旧的字段值 [英] Spring AOP - get old field value before calling the setter

查看:25
本文介绍了Spring AOP - 在调用 setter 之前获取旧的字段值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的,我目前正在使用 Spring AOP (v4) 和 AspectJ 以及 load-time-weaver.

Dear all I am curently using Spring AOP (v4) and AspectJ with load-time-weaver.

我目前正在寻找一种将脏标志机制添加到我的 bean 中的方法.因此,我认为在调用我的 bean 的 setter 之前使用 AOP 调用方法.我已经实现了这一点,但是如何在修改之前访问旧字段值?或者有没有办法获取字段名称,以便我可以在调用 setter 之前调用 getter?

I am looking currently for a way to add a dirty flag mechanism into my beans. Therefore I I though of using AOP to call a method before a setter of my beans get called. This I achieved already, but how can I access the old field value beforeit get modified? Or is there a way to get the field name so I can call the getter before the setter get called?

谁能在这里给我提供一些例子,切入点/建议必须看起来像如何作为参数传递?

Can anybody provide me here some example how the pointcut/advice has to look like to get it a passed as arguments?

@Aspect
public class MyAspect {

  @Before("execution(* foo.*.set*(..))") 
  public void beforeSetterCalled(JoinPoint joinPoint){
    System.out.println("beforeSetter");
  }
}

不幸的是,Spring AOP 似乎不支持set()"字段切入点构造,这是正确的吗?或以某种方式存在以使用它?

Unfortunately it seems that Spring AOP does not support the "set()" field-pointcut construct, is this correct? OR exists someway to use this?

感谢您的帮助.

推荐答案

我建议将完整的 AspectJ 与 set() 切入点结合使用,以获得有效的解决方案.但是,如果您不介意使用涉及反射的缓慢、丑陋的解决方案,您也可以这样做:

I would recommend to use full AspectJ in combination with a set() pointcut in order to get an efficient solution. But if you do not mind having a slow, ugly solution involving reflection you can also do something like this:

package de.scrum_master.app;

public class Person {
    private int id;
    private String firstName;
    private String lastName;

    public Person(int id, String firstName, String lastName) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public int getId() { return id; }
    public String getFirstName() { return firstName; }
    public String getLastName() { return lastName; }

    public void setId(int id) { this.id = id; }
    public void setFirstName(String firstName) { this.firstName = firstName; }
    public void setLastName(String lastName) { this.lastName = lastName; }

    @Override
    public String toString() { return "Person [" + id + ", " + firstName + " " + lastName + "]"; }

    public static void main(String[] args) {
        Person albert = new Person(1, "Albert", "Camus");
        Person audrey = new Person(2, "Audrey", "Hepburn");
        System.out.println(albert);
        System.out.println(audrey);
        System.out.println();
        albert.setId(8);
        albert.setLastName("Einstein");
        audrey.setId(9);
        audrey.setLastName("Tautou");
        System.out.println();
        System.out.println(albert);
        System.out.println(audrey);
    }
}

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.SoftException;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class SetterInterceptor {
    @Before("execution(* set*(*)) && target(instance) && args(newValue)")
    public void beforeSetterCalled(JoinPoint thisJoinPoint, Object instance, Object newValue) {
        String methodName = thisJoinPoint.getSignature().getName();
        try {
            System.out.println(
                methodName.substring(3) + ": " +
                instance
                    .getClass()
                    .getMethod(methodName.replaceFirst("set", "get"))
                    .invoke(instance) +
                " -> " + newValue
            );
        } catch (Exception e) {
            throw new SoftException(e);
        }
    }
}

控制台日志:

Person [1, Albert Camus]
Person [2, Audrey Hepburn]

Id: 1 -> 8
LastName: Camus -> Einstein
Id: 2 -> 9
LastName: Hepburn -> Tautou

Person [8, Albert Einstein]
Person [9, Audrey Tautou]

这篇关于Spring AOP - 在调用 setter 之前获取旧的字段值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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