在以下测试案例中,CGLIB不拦截直接字段t。 我可以使用CGLIB吗?
public class Test {
@Test
public void testCGLib() {
A a = (A) Enhancer.create(A.class, new Class[] {}, new B());
System.out.println(a.t);
a.t();
}
public static class A {
public int t = 0;
public void t() {
System.out.println("bbb");
}
}
public static class B implements LazyLoader {
@Override
public Object loadObject() throws Exception {
System.out.println("xxx");
return new A();
}
}
}
答案 0 :(得分:0)
不,那是不可能的。字段访问不会委托给定义字段的类的某些字节代码。它由使用该字段的方法直接加载。 (在您的情况下,这是Test#testCGLib
。)
cglib创建一个子类并拦截方法调用。但是不能覆盖字段,它们不是polimorphic,有或没有cglib。因此,您永远不能拦截现场访问。您只能隐藏子类中的字段。
但即使您在检测类中隐藏了字段A#t
:由于cglib类在编译时不可见,因此您无法通过检测类型引用该字段。如果已检测的班级A$$cglib
有一个字段t
,您只能通过
a.getClass().getField("x").get(a)
为了模拟某种动态字段绑定。 (基本上,这些方法是动态绑定的,会导致动态选择 right 字段。