下面会分别对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:
User{name='null', age=0}
User{name='mzd', age=456}
User{name='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:
User{name='zyz', age=123}
****
User{name='zyz', age=123}
****
User{name='mzd', age=123}
3
CGLIB$FACTORY_DATA
name
age
****
User{name='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:
User{name='mzd', age=456}
User{name='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动态代理创建的对象必须用接口接收