Hibernate之Load懒加载机制

来源:互联网 发布:ubuntu卸载软件的命令 编辑:程序博客网 时间:2024/05/06 19:10

开篇需要说明一下,hibernate懒加载机制,并不是绝对依赖于cglib的,具体请看代理工厂ProxyFactory,hibernate为该代理工厂提供了四种实现,分别是CGLIBProxyFactory,Dom4jProxyFactory,JavassistProxyFactory,MapProxyFactory,其中CGLIBProxyFactory已经废弃了,默认使用的是JavassistProxyFactory,该实现依赖于javassist组件。

下面,我将自己整理的,hibernate中关于懒加载关键部分的实现Demo展示出来,希望能帮助大家理解。

1. 对象懒加载器

package com.demo.hibernate.proxy;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Date;import java.util.HashMap;import java.util.Map;import org.hibernate.util.ReflectHelper;import com.demo.hibernate.bean.Event;import javassist.util.proxy.MethodFilter;import javassist.util.proxy.MethodHandler;import javassist.util.proxy.ProxyFactory;import javassist.util.proxy.ProxyObject;/** * 对象懒加载器 * @author guor * @version 2014-6-30 */public class LazyInitializer implements MethodHandler {/** * 模拟数据库容器 */private static Map<String, Event> dbs = new HashMap<String, Event>();static {dbs.put("1", new Event("first event", new Date()));dbs.put("2", new Event("second event", new Date()));dbs.put("3", new Event("third event", new Date()));dbs.put("4", new Event("forth event", new Date()));}private final String id;/** * 被代理的类 */private final Class<?> sourceClass;/** * 代理对象 */private Object target;/** * 数据是否加载的标记 */private boolean initialized;private LazyInitializer(final Class<?> sourceClass, String id) {this.sourceClass = sourceClass;this.id = id;}/** * 获取一个动态代理对象 *  * @param sourceClass 被代理的类 * @param id 数据的唯一标识 * @return 返回代理的对象 */public static ProxyObject load(final Class<?> sourceClass, String id) {final LazyInitializer instance = new LazyInitializer(sourceClass, id);ProxyFactory factory = new ProxyFactory();factory.setSuperclass(sourceClass);/** * 跳过finalize方法的代理 */factory.setFilter(FINALIZE_FILTER);Class<?> cl = factory.createClass();try {ProxyObject obj = (ProxyObject) cl.newInstance();obj.setHandler(instance);return obj;} catch (Exception e) {e.printStackTrace();}return null;}private final Object getImplementation() {initialize();return target;}private final void initialize() {if (!initialized) {this.target = dbs.get(this.id);initialized = true;}}/** * 方法过滤器,动态创建的代理类,不代理finalize方法 */private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {public boolean isHandled(Method m) {return !(m.getParameterTypes().length == 0 && m.getName().equals("finalize"));}};@Overridepublic Object invoke(final Object proxy, final Method thisMethod, final Method proceed, final Object[] args)throws Throwable {/** * 从数据库加载数据 */Object target = getImplementation();try {final Object returnValue;if (ReflectHelper.isPublic(this.sourceClass, thisMethod)) {if (!thisMethod.getDeclaringClass().isInstance(target)) {throw new ClassCastException(target.getClass().getName());}returnValue = thisMethod.invoke(target, args);} else {if (!thisMethod.isAccessible()) {thisMethod.setAccessible(true);}returnValue = thisMethod.invoke(target, args);}return returnValue == target ? proxy : returnValue;} catch (InvocationTargetException ite) {throw ite.getTargetException();}}}

2. 使用示例

package com.demo.hibernate.proxy;import com.demo.hibernate.bean.Event;public class Main {public static void main(String[] args) {Event e = (Event) LazyInitializer.load(Event.class, "1");System.out.println(e.getTitle());}}

1 0