论坛首页 Java企业应用论坛

关于CGLIB

浏览 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的。
   发表时间: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的?
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()方法:
	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。
1 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics