1

作为一个实验,我通过“加载”获取了一个 Hibernate 实体 pojo,并通过正常的序列化将其写入文件。我通过正常的反序列化再次通过单独的程序读取该文件,然后使用反射查找实体对象的代理类包含的字段和方法。

令我惊讶的是,它向我展示了代理类中包含的所有方法(例如,'getHibernateLazyInitializer()' 或 'CGLIB$SET_THREAD_CALLBACKS(net.sf.cglib.proxy.Callback[])' 等)

更重要的是,我能够在反序列化实例上调用“getHibernateLazyInitializer()”方法!现在,如果代理代码是动态生成的,并且如果在创建它的 JVM 关闭后该类不存在,我怎么能调用该方法?方法字节码是否也通过它们的代理为 Hibernate pojo 序列化/反序列化?

4

3 回答 3

0

不,它没有。如果您尝试反序列化 Java 进程中的类路径不知道该类的对象,则会出现错误。

于 2012-04-05T07:36:01.980 回答
0

由于您实际序列化的对象实例不是您的实体类本身,而是扩展该类的代理,因此很明显,如果您反序列化您得到的不是您的实体实例,而是再次获得代理。

于 2012-04-05T07:44:59.673 回答
0

好的,我又调试了一些,发现在序列化代理实例时,Hibernate 实际上编写了一个 SerializableProxy 的实例。发生这种情况是因为代理类实现了一个接口“HibernateProxy”,其中有一个“writeReplace()”方法,该方法返回所述 SerializableProxy 实例。

当这个实例被反序列化时,SerializableProxy 的 readResolve() 会启动并返回一个 HibernateProxy 对象,该对象是根据 SerializableProxy 实例中提到的信息创建的,并依次使用 CGLib Enhancer。这就是为什么我能够看到所有这些方法并调用它们。

底线:流中没有写入任何方法代码。Hibernate 通过 writeReplace 更改对象本身,然后在读回该对象时使用 readResolve 和 CGLIb 重新创建代理。

于 2012-04-05T09:12:26.817 回答