cglib可以用来截取直接字段吗?
问题描述:
在下面的测试用例中,直接字段t不被CGLIB拦截。 那么我可以使用CGLIB吗?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();
}
}
}
答
不,那是不可能的。字段访问不会委派给定义字段的类的某些字节代码。它是由使用该字段的方法直接加载的。 (在你的情况下,这是Test#testCGLib
。)
cglib创建一个子类并拦截方法调用。字段可以不被覆盖,它们不是多态的,有或没有cglib。因此,你永远不能拦截现场访问。您只能隐藏子类中的字段。
但即使您在工具类中隐藏了字段A#t
:由于cglib类在编译时不可见,因此无法通过检测类型引用该字段。如果仪表类A$$cglib
过场t
,你可以通过
a.getClass().getField("x").get(a)
为了模仿某种充满活力的领域结合的唯一访问它。 (基本上,这些方法是动态绑定的,会导致动态选择字段。