powerwind 发表于 2006-9-14 19:52

今天看到有关ASM的资料和CGLIB的资料,应该是它们在作怪了.
ASM可以直接修改JAVA类文件的 bytecode,直接写入虚拟机指令,这还有什么做不什么来的呢?
而CGLIB大概是把ASM做得更"JAVA"些.
以后有机会再慢慢看看怎么回事.

ASM的介绍
asm的eclipse插件

[ 本帖最后由 powerwind 于 2006-9-14 19:56 编辑 ]

thiswwww 发表于 2006-9-28 00:38

hibernate映射javabean,其实就是javabean的实例。

powerwind 发表于 2006-9-28 01:41

好像有资料介绍说,hibernate为持久化类创建代理子类.
应该不只是javabean的实例这么简单.
ASM和CGLIB是它实现的底层技术

活在阳光下 发表于 2006-10-11 21:07

反射机制确实有能力访问private级别的Field和Method,如:
//TestReflect.java 开始
import java.lang.reflect.*;

class Reflect{
        private int id;
       
        public Reflect(){
        }
       
        private void setId(int id){
                this.id=id;
        }
       
        public int getId(){
                return id;
        }
}

public class TestReflect{
        public static void main(String [] arg) throws Exception{
                Class class_tr=Class.forName("Reflect");
                Reflect tr=(Reflect)class_tr.newInstance();
                Field f_id=class_tr.getDeclaredField("id");
                f_id.setAccessible(true);
                f_id.setInt(tr,2);
                System.out.println("private filed 'id' :"+tr.getId());
        }
}
//结束

运行结果打印出:
private filed 'id' :2

如果反射机制不能访问private级别的Field或者Method,就失去了它了意义,因为"反射机制"是:"是指程序可以访问、检测和修改它本身状态或行为的一种能力".

然而Hibernate是如何做到的,是否是通过反射机制就只能看其源码了...

powerwind 发表于 2006-10-12 13:18

原来如此!
因为对反射机制不了解,一直以为不能访问private级别的Field或者Method。
感谢楼上的解答。

活在阳光下 发表于 2006-10-12 13:35

呵,总算解决了,恭喜!

powerwind 发表于 2006-10-12 16:50

在 <<J2ee development without ejb>>中文版 283页,有这样一句:

请注意,如果映射JavaBean属性,只跟Hibernate持久化相关的那些getter和setter可以是protected甚至private的,以保证由应用程序驱动字段的可见度.
页尾有这样的注释:


译者注:然而据译者的观察,如果将 setter声明为private,会导致 Hibernate 无法使用CGLIB优化的反射机制,只能通过标准的JAVA反射机制为持久对象



所有的持久化类(persistent classes)都要求有无参的构造器,因为Hibernate必须使用Java反射机制来为你创建对象。构造器(constructor)的访问级别可以是private,然而当生成运行时代理(runtime proxy)的时候则要求使用至少是package 级别的访问控制,这样在没有字节码指令(bytecode instrumentation)的情况下,从持久化类里获取数据会更有效率。


所有的持久化类(persistent classes)都要求有无参的构造器,因为Hibernate必须使用Java反射机制来为你创建对象。构造器(constructor)的访问级别可以是private,然而当生成运行时代理(runtime proxy)的时候则要求使用至少是package 级别的访问控制,这样在没有字节码指令(bytecode instrumentation)的情况下,从持久化类里获取数据会更有效率。

综合以前所有发现和楼主的解释,Hibernate应该是首选CGLIB,次选反射机制。

[ 本帖最后由 powerwind 于 2006-10-12 16:53 编辑 ]
页: 1 [2]
查看完整版本: [已解决]Hibernate为什么可以访问private的setXXX()方法