动态代理对象的属性注入
Posted 技术无产者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态代理对象的属性注入相关的知识,希望对你有一定的参考价值。
下面会分别对Jdk和Cglib两种类型的动态代理的对象进行分析
1.Cglib
1> 直接通过反射创建代理对象
User user=new User("zyz",123);
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(user.getClass());
enhancer.setInterfaces(user.getClass().getInterfaces());
enhancer.setCallback(new NoOp()
@Override
public int hashCode()
return super.hashCode();
);
User u=(User) enhancer.create();
System.out.println(u);
BeanUtil.setFieldValue(u,"name","mzd");
BeanUtil.setFieldValue(u,"age",456);
System.out.println(u);
u.name="cyq";
System.out.println(u);
// res:
Username='null', age=0
Username='mzd', age=456
Username='cyq', age=456
没有指定代理的对象时,直接修改和通过强制注入都是可以修改代理对象的属性值的
2> 代理某个对象
User user=new User("zyz",123);
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(user.getClass());
enhancer.setInterfaces(user.getClass().getInterfaces());
enhancer.setCallback(new MethodInterceptor()
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable
return methodProxy.invoke(user,objects);
);
User u=(User) enhancer.create();
System.out.println(u);
BeanUtil.setFieldValue(u,"name","mzd");
BeanUtil.setFieldValue(u,"age",456);
System.out.println("****");
System.out.println(u);
BeanUtil.setFieldValue(user,"name","mzd");
System.out.println("****");
System.out.println(user);
System.out.println( u.getClass().getFields().length);
for (Field field:u.getClass().getFields())
System.out.println(field.getName());
System.out.println("****");
u.name="qaz";
System.out.println(u);
System.out.println("****");
// res:
Username='zyz', age=123
****
Username='zyz', age=123
****
Username='mzd', age=123
3
CGLIB$FACTORY_DATA
name
age
****
Username='mzd', age=123
****
Process finished with exit code 0
由结果可见,创建了一个user对象,用cglib来代理这个类,直接改变代理类的属性值,是不起作用的,虽然修改代理类u的属性,但是输出u结果还是输出的被代理对象user本身的属性值,我猜测是因为User是它的父类,由于编译看左边的缘故所以优先输出User对象的属性? 这点我也存在疑惑。总之,若指定了代理的对象,直接修改生成代理对象的属性是不起作用的。
但是直接修改被代理类的值,这时候代理类的值是变化的
2.JDK动态代理
1>直接通过反射创建
User user=new User();
User user1 = user.getClass().newInstance();
BeanUtil.setFieldValue(user1,"name","mzd");
BeanUtil.setFieldValue(user1,"age",456);
System.out.println(user1);
user1.name="cyq";
System.out.println(user1);
// res:
Username='mzd', age=456
Username='cyq', age=456
反射创建可以修改属性的值
2>
User user=new User("zyz",1321);
User user1 = user.getClass().newInstance();
UserService1 u = (UserService1) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), user.getClass().getInterfaces(), new InvocationHandler()
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
return method.invoke(user, args);
);
System.out.println(u);
BeanUtil.setFieldValue(u,"name","mzd");
BeanUtil.setFieldValue(u,"age",456);
System.out.println("****");
System.out.println(u);
BeanUtil.setFieldValue(user,"name","mzd");
System.out.println("****");
System.out.println(user);
System.out.println( u.getClass().getFields().length);
for (Field field:u.getClass().getFields())
System.out.println(field.getName());
JDK动态代理更无法更改属性,因为jdk动态代理创建的对象必须用接口接收
以上是关于动态代理对象的属性注入的主要内容,如果未能解决你的问题,请参考以下文章
IOC 控制反转Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 创建 事件监听器 对应的 动态代理 | 动态代理的数据准备 | 创建调用处理程序 | 创建动态代理实例对象 )(代码片