论坛首页 Java版 Hibernate

关于CGLIB

浏览 7695 次
锁定老贴子 主题:关于CGLIB
该帖已经被评为精华帖
作者 正文
最后更新时间:2003-12-22
yehs220 写道
还有,也不是像你说的那样(Hibernate用cglib来POJO转换成PO),hibernate用cglib只不过是为了实现一部分的lazy loading功能,即使hibernate不用cglib一样可以工作,只不过可能有少许的性能损失。

Robin 写道

cglib-asm.jar:

CGLIB库,Hibernate用它来实现PO字节码的动态生成,非常核心的库,必须使用的jar包


hibernate不是用cglib来完成POJO-->PO的转换?而且hibernate都不用cglib也行?这好像跟robin讲的不太一样。

另外2.1版本中,cglib-asm也换成了cglib2.jar,这是sourceforge.net上的一个开源项目(是Gavin贡献的代码吗?)的较新版本了。说明hibernate一直是在用它。

我很想知道hibernate是如何把我们POJO的bytecode变成PO的bytecode的。
   
最后更新时间:2003-12-22
检查源码,发现确实只有CGLIBLazyInitializer一个类实现了MethodInterceptor,它的方法intercept():
[code:1]if (constructed) {
Object result = invoke(method, args, obj);
if (result==INVOKE_IMPLEMENTATION) {
return proxy.invoke( getImplementation(), args );
}
else {
return result;
}
}
else {
//while constructor is running
return proxy.invokeSuper(obj, args);
}[/code:1]
即使用cglib做搜索关键字,也只有如下文件存在使用:
[code:1]AbstractEntityPersister.java ― hibernate21/java/net/sf/hibernate/persister (3 匹配)
CGLIBLazyInitializer.java ― hibernate21/java/net/sf/hibernate/proxy (4 匹配)
ComponentType.java ― hibernate21/java/net/sf/hibernate/type (2 匹配)
Environment.java ― hibernate21/java/net/sf/hibernate/cfg (2 匹配)
HibernateProxyHelper.java ― hibernate21/java/net/sf/hibernate/proxy
ReflectHelper.java ― hibernate21/java/net/sf/hibernate/util (4 匹配)
SessionFactoryImpl.java ― hibernate21/java/net/sf/hibernate/impl[/code:1]
似乎最后也还是归结到CGLIBLazyInitializer。那么就有问题,cglib在hibernate中的作用是不是如yehs220所言“只不过是为了实现一部分的lazy loading功能”?POJO究竟是怎样转化为PO的?
   
0 请登录后投票
最后更新时间:2003-12-22
引用

hibernate用cglib只不过是为了实现一部分的lazy loading功能,即使hibernate不用cglib一样可以工作,

这句话我确实说的不对,我收回并道歉

但我确实没有看到hibernate在除了实现动态代理的其他地方有对Entity Class进行增强(不过我对cglib的了解也仅限于Interceptor)。
   
0 请登录后投票
最后更新时间:2003-12-23
引用
但我确实没有看到hibernate在除了实现动态代理的其他地方有对Entity Class进行增强

呵呵,这正是我现在的疑惑啊。
PO你在哪里?
   
0 请登录后投票
最后更新时间:2003-12-23
哦,追踪了一下流程,从一个load方法开始,发现有proxy的会最终进入到CGLIBLazyInitializer的getProxy()方法:
[code:1] public static HibernateProxy getProxy(Class persistentClass, Class[] interfaces, Method getIdentifierMethod, Serializable id, SessionImplementor session) throws HibernateException {
if ( persistentClass.isInterface() ) {
Class[] tempInterfaces = new Class[interfaces.length+1];
System.arraycopy(interfaces, 0, tempInterfaces, 0, interfaces.length);
tempInterfaces[interfaces.length] = persistentClass;
interfaces = tempInterfaces;
}
try {
return (HibernateProxy) Enhancer.enhance(
(interfaces.length==1) ?
persistentClass :
null,
interfaces,
new CGLIBLazyInitializer(persistentClass, interfaces, id, getIdentifierMethod, session),
persistentClass.getClassLoader()
);
}
catch (Throwable t) {
LogFactory.getLog(LazyInitializer.class).error("CGLIB Enhancement failed", t);
throw new HibernateException( "CGLIB Enhancement failed", t );
}
}[/code:1]
就是在这里完成了PO的生成,enhance()返回的接口HibernateProxy就是我们使用的PO。它设定了callback是new CGLIBLazyInitializer(persistentClass, interfaces, id, getIdentifierMethod, session),也就是intercepter,然后实现了intercept()方法,在这里完成了对POJO对象的替换(当然,具体实现在sessionimp、Loader、Interceptor等还有复杂的过程)。于是我们就开始以自己不察觉的方式使用PO。
   
0 请登录后投票
论坛首页 Java版 Hibernate

跳转论坛:
JavaEye推荐