cglib MethodInterceptor方法拦截器中获取被代理类对象成员变量的值

需要掌握:设计模式-代理模式-cglib动态代理

例子

创建maven工程

略

修改pom.xml

添加依赖:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2</version>
</dependency>

需要jar包

  • asm-7.1.jar
  • cglib-3.3.0.jar

演员类(目标类)

同 设计模式-代理模式-java

public class Actor {
    private String name = "韩梅梅";

    public boolean deal(int money, int days) {
        System.out.println(String.format("Actor==收到合约,酬劳:%s万,合约期:%s天",money,days));
        System.out.println("Actor==演戏");
        return true;
    }
}

代理类(经纪人类)

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxy {

    static class MethodInterceptorImpl implements MethodInterceptor{
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            // XXXXX关键:object 是代理对象,通过该代理对象获取其类的 Class,是代理类的 Class,有大量额外信息,不可用
            //  Class clazz = object.getClass();
            // XXXXX关键:通过 method 获取其类的Class
            Class clazz = method.getDeclaringClass();
            Field[] declaredFields = clazz.getDeclaredFields();
            for(Field field : declaredFields){
                // 设置成员变量的访问权限,即使private也能访问
                field.setAccessible(true);
                // XXXXX关键:获取成员变量的值,传入代理对象
                Object fieldObject = field.get(object);
                System.out.println("成员变量 "+field.getName()+" 的值是:"+fieldObject);
            }
            // 调用目标类对象的方法
            Object res = methodProxy.invokeSuper(o, args);
            return res;
        }
    }
    public static Actor get(){
        Actor actor= (Actor) Enhancer.create(Actor.class, new MethodInterceptorImpl());

        return actor;
    }
}

导演类(主启动类)

public class Director {

    public static void main(String[] args) {

        Actor actor = CglibProxy.get();
        int money=350;
//        int money=280;
        int days=300;
        System.out.println(String.format("Director==谈合作:%s万,%s天,可以吗?",money,days));
        boolean b=actor.deal(money,days);
        if(b) {
            System.out.println("Director==开拍");
        }else{
            System.out.println("Director==演员没谈成,不能开拍");
        }
    }

}

注意: debug运行时,会产生一些问题,方法前后的代码会执行好几次,而且方法后面的代码会先执行。正常运行时不会发生