cglib可以用来拦截直接场吗?

时间:2012-03-19 08:41:01

标签: java cglib

在以下测试案例中,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();
    }
}
}

1 个答案:

答案 0 :(得分:0)

不,那是不可能的。字段访问不会委托给定义字段的类的某些字节代码。它由使用该字段的方法直接加载。 (在您的情况下,这是Test#testCGLib。)

cglib创建一个子类并拦截方法调用。但是不能覆盖字段,它们不是polimorphic,有或没有cglib。因此,您永远不能拦截现场访问。您只能隐藏子类中的字段。

但即使您在检测类中隐藏了字段A#t:由于cglib类在编译时不可见,因此您无法通过检测类型引用该字段。如果已检测的班级A$$cglib有一个字段t,您只能通过

访问它
a.getClass().getField("x").get(a)

为了模拟某种动态字段绑定。 (基本上,这些方法是动态绑定的,会导致动态选择 right 字段。