在调用其对应的set方法时获取对象值

时间:2019-08-14 17:45:35

标签: java spring spring-aop

我想使用spring AOP(@Before)获得修改后的对象的值。 我有以下课程:

package com.mypack;
public class Person {
    private String id;
    private String firstName;
    private String lastName;

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

    public void setId(String id) { this.id = id; }
    public void setFirstName(String firstName) { this.firstName = firstName; }
    public void setLastName(String lastName) { this.lastName = lastName; }
    public String toString() { return "Person[" + id + ",  
   + firstName + ", " + lastName+ "]"; }
}

Details类:

package com.mypack;
public class Details extends Person{

    private String address;
    private String contactNum;
    //getters and setters
    public String toString() { return "Details[" + address + ", 
    " + contactNum+ "]"; }

}

AspectSetterInterceptor类:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class AspectSetterInterceptor {
     @Before("execution(* com.mypack.Details.set*(*))")
        public void before(JoinPoint joinPoint) throws Throwable {
        Object[] signatureArgs = joinPoint.getArgs();
            for (Object signatureArg : signatureArgs) {
                Person obj = (Person) signatureArg;
                System.out.println("Before : " + obj.getFirstName() + " ---- "
                        + obj.getId());

            }

        }
}

测试类:

public class ChangeTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.register(AspectConfig.class);
        ctx.refresh();
        //Details userService = ctx.getBean(Details.class);
        Details obj1 = new Details();
        obj1.setAddress("xx 202");
        obj1.setContactNum("2124551234");
        obj1.setId("242");
        obj1.setFirstName("John");
        obj1.setLastName("John");

        Details obj2 = new Details();
        obj2.setAddress("ASDf 202");
        obj2.setContactNum("234544565656");
        obj2.setId("23689");
        obj2.setFirstName("Sam");
        obj2.setLastName("S");

        System.out.println("obj1 : " + obj1);
        System.out.println("obj2 : " + obj2);

        obj2.setFirstName("Samuel");
    }

}

也尝试过此处提到的Spring AOP - get old field value before calling the setter

-编辑- 当执行ChangeTest类时,它将打印obj1和obj2的值(该类中的toString()方法被覆盖)。它没有达到AspectSetterInterceptor中提到的before ..方法。请指教。

PS:我的场景是在有人使用set *(..)方法时打@Before方面。在上面的示例中,我给出了一个简单的类Details,它扩展了Person类,因此,在这些类中任何时候调用set *(..)方法时,都应调用@before方面,类似地,我希望在我的应用程序中使用任何set **( ..)方法被调用,我想调用@Before。有没有更好的方法可以遵循。TIA。

2 个答案:

答案 0 :(得分:0)

您为方法setId(int i)输入一个int,但在主方法中,您传递了一个String。 obj1.setId("242");您需要做的是传递一个整数obj1.setId(242);,就像做一个旁注一样,由于您正在做toString(),所以要覆盖System.out.println("obj1 : " + obj1);方法,但是打印obj只会打印地址(一堆随机数字和字母)。

答案 1 :(得分:0)

您的切入点定义@Before("execution(* com.mypack.set*(*))")意味着它会在类mypack的所有设置方法上触发。

您想要的可能是

@Before("execution(* com.mypack.Person.set*(*))") // all setters on person

@Before("execution(* com.mypack.*.set*(*))") // all setters on all classes in package

@Before("execution(* com.mypack..set*(*))") // all setters in all classes in all subpackages