好好学习了一下,Hibernate 方面的书,温故而知新,可以为师亦.
我们如果使用用延迟加载实际上用的是Hibernate 中使用的代理类.它默认依赖 cglib 来实现.
Hibernate 中使用 CGLIB 和 javassist 来完成延迟加的.
CGLIB 如下:
依懒包:cglib-2.1.3.jar
首先定义一个供调用的接口:com.isw2.hibernate.test.interfaces.ITest.java
package com.isw2.hibernate.test.interfaces; public interface ITest { public void testFirst(); public void testSecond(); }
接着要定义一个拦截器:com.isw2.hibernate.test.TestITest.java
package com.isw2.hibernate.test; import java.lang.reflect.Method; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * MethodInterceptor 是一个拦截器接口 * @author Administrator * */ public class TestITest implements MethodInterceptor { public Object intercept(Object object, Method method, Object[] objArr, MethodProxy methodProxy) throws Throwable { System.out.println("display" + method.getName()); return null; } }
这样就可以使用了.
public static void main(String[] args) { //过滤器类 MethodInterceptor methodInterceptor = new TestITest(); Enhancer eh = new Enhancer(); //设置接口 eh.setSuperclass(ITest.class); //设置调用过滤器 eh.setCallback(methodInterceptor); //创建代理类 ITest test = (ITest) eh.create(); test.testFirst(); test.testSecond(); }
javassist执行的是字节码操作.相关如下:
依懒Jar 包:javassist.jar
首先建一个使用类com.isw2.bean.ButtBean.java
package com.isw2.bean; public class ButtBean { public void disPlay() { System.out.println("ButtBean.disPlay"); } }
javassist 的使用:
try { //ClassPool 是CtClass 的工厂 //CtClass 类似于一个代理类,通过它获取代理类运行时内容 CtClass ctclass = ClassPool.getDefault().get( "com.isw2.bean.ButtBean"); String oldMethod = "disPlay"; //CtMethod 代表 CtClass 中的方法. CtMethod ctMethod = ctclass.getDeclaredMethod(oldMethod); String newMehtod = oldMethod + "New"; ctMethod.setName(newMehtod); CtMethod ctNewMethod = CtNewMethod.copy(ctMethod, oldMethod, ctclass, null); StringBuffer sbuffer = new StringBuffer(); sbuffer.append("{\nSystem.out.println(\"ButtBean.disPlay " + "javassist help compile\");\n}"); ctNewMethod.setBody(sbuffer.toString()); ctclass.addMethod(ctNewMethod); System.out.println("输出结果:"); // 这里要注意的是 BuffBean 必在这之前没有补JVM 加载,否则在这里会出错 ButtBean butt = (ButtBean) ctclass.toClass().newInstance(); butt.disPlay(); } catch (NotFoundException e) { e.printStackTrace(); } catch (CannotCompileException e2) { e2.printStackTrace(); } catch (Exception e3) { e3.printStackTrace(); }
相关的操作
http://blog.csdn.net/yadandan520_ya/archive/2009/03/04/3956867.aspx
http://brighter.iteye.com/blog/224629
都分别给了详细的操作说明.
在org.hibernate.cfg.Environment.buildBytecodeProvider 里,将 "cglib",改为 "javassist" 这样,Hibernate 就会使用 javassist 来生成代理对象了.