浏览 16575 次
锁定老帖子 主题:关于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的。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2003-12-22
检查源码,发现确实只有CGLIBLazyInitializer一个类实现了MethodInterceptor,它的方法intercept():
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);; } 即使用cglib做搜索关键字,也只有如下文件存在使用: 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 似乎最后也还是归结到CGLIBLazyInitializer。那么就有问题,cglib在hibernate中的作用是不是如yehs220所言“只不过是为了实现一部分的lazy loading功能”?POJO究竟是怎样转化为PO的? |
|
返回顶楼 | |
发表时间:2003-12-22
引用 hibernate用cglib只不过是为了实现一部分的lazy loading功能,即使hibernate不用cglib一样可以工作, 这句话我确实说的不对,我收回并道歉 。 但我确实没有看到hibernate在除了实现动态代理的其他地方有对Entity Class进行增强(不过我对cglib的了解也仅限于Interceptor)。 |
|
返回顶楼 | |
发表时间:2003-12-23
引用 但我确实没有看到hibernate在除了实现动态代理的其他地方有对Entity Class进行增强
呵呵,这正是我现在的疑惑啊。 PO你在哪里? |
|
返回顶楼 | |
发表时间:2003-12-23
哦,追踪了一下流程,从一个load方法开始,发现有proxy的会最终进入到CGLIBLazyInitializer的getProxy()方法:
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 );; } } 就是在这里完成了PO的生成,enhance()返回的接口HibernateProxy就是我们使用的PO。它设定了callback是new CGLIBLazyInitializer(persistentClass, interfaces, id, getIdentifierMethod, session),也就是intercepter,然后实现了intercept()方法,在这里完成了对POJO对象的替换(当然,具体实现在sessionimp、Loader、Interceptor等还有复杂的过程)。于是我们就开始以自己不察觉的方式使用PO。 |
|
返回顶楼 | |