1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
| public class JavassistProxyFactory implements ProxyFactory { private static final String FINALIZE_METHOD = "finalize"; private static final String WRITE_REPLACE_METHOD = "writeReplace";
public JavassistProxyFactory() { try { Resources.classForName("org.apache.ibatis.javassist.util.proxy.ProxyFactory"); } catch (Throwable var2) { throw new IllegalStateException("Cannot enable lazy loading because Javassist is not available. Add Javassist to your classpath.", var2); } }
public Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { return JavassistProxyFactory.EnhancedResultObjectProxyImpl.createProxy(target, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs); }
public Object createDeserializationProxy(Object target, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { return JavassistProxyFactory.EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs); }
static Object crateProxy(Class<?> type, MethodHandler callback, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { org.apache.ibatis.javassist.util.proxy.ProxyFactory enhancer = new org.apache.ibatis.javassist.util.proxy.ProxyFactory(); enhancer.setSuperclass(type);
try { type.getDeclaredMethod("writeReplace"); } catch (NoSuchMethodException var10) { enhancer.setInterfaces(new Class[]{WriteReplaceInterface.class}); } catch (SecurityException var11) { }
Class<?>[] typesArray = (Class[])constructorArgTypes.toArray(new Class[constructorArgTypes.size()]); Object[] valuesArray = constructorArgs.toArray(new Object[constructorArgs.size()]);
Object enhanced; try { enhanced = enhancer.create(typesArray, valuesArray); } catch (Exception var9) { throw new ExecutorException("Error creating lazy proxy. Cause: " + var9, var9); }
((Proxy)enhanced).setHandler(callback); return enhanced; }
private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy implements MethodHandler { private EnhancedDeserializationProxyImpl(Class<?> type, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { super(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs); }
public static Object createProxy(Object target, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { Class<?> type = target.getClass(); JavassistProxyFactory.EnhancedDeserializationProxyImpl callback = new JavassistProxyFactory.EnhancedDeserializationProxyImpl(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs); Object enhanced = JavassistProxyFactory.crateProxy(type, callback, constructorArgTypes, constructorArgs); PropertyCopier.copyBeanProperties(type, target, enhanced); return enhanced; }
public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable { Object o = super.invoke(enhanced, method, args); return o instanceof AbstractSerialStateHolder ? o : methodProxy.invoke(o, args); }
protected AbstractSerialStateHolder newSerialStateHolder(Object userBean, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { return new JavassistSerialStateHolder(userBean, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs); } }
private static class EnhancedResultObjectProxyImpl implements MethodHandler { private final Class<?> type; private final ResultLoaderMap lazyLoader; private final boolean aggressive; private final Set<String> lazyLoadTriggerMethods; private final ObjectFactory objectFactory; private final List<Class<?>> constructorArgTypes; private final List<Object> constructorArgs;
private EnhancedResultObjectProxyImpl(Class<?> type, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { this.type = type; this.lazyLoader = lazyLoader; this.aggressive = configuration.isAggressiveLazyLoading(); this.lazyLoadTriggerMethods = configuration.getLazyLoadTriggerMethods(); this.objectFactory = objectFactory; this.constructorArgTypes = constructorArgTypes; this.constructorArgs = constructorArgs; }
public static Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { Class<?> type = target.getClass(); JavassistProxyFactory.EnhancedResultObjectProxyImpl callback = new JavassistProxyFactory.EnhancedResultObjectProxyImpl(type, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs); Object enhanced = JavassistProxyFactory.crateProxy(type, callback, constructorArgTypes, constructorArgs); PropertyCopier.copyBeanProperties(type, target, enhanced); return enhanced; }
public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable { String methodName = method.getName();
try { synchronized(this.lazyLoader) { if ("writeReplace".equals(methodName)) { Object original; if (this.constructorArgTypes.isEmpty()) { original = this.objectFactory.create(this.type); } else { original = this.objectFactory.create(this.type, this.constructorArgTypes, this.constructorArgs); }
PropertyCopier.copyBeanProperties(this.type, enhanced, original); if (this.lazyLoader.size() > 0) { return new JavassistSerialStateHolder(original, this.lazyLoader.getProperties(), this.objectFactory, this.constructorArgTypes, this.constructorArgs); }
return original; }
if (this.lazyLoader.size() > 0 && !"finalize".equals(methodName)) { if (!this.aggressive && !this.lazyLoadTriggerMethods.contains(methodName)) { String property; if (PropertyNamer.isSetter(methodName)) { property = PropertyNamer.methodToProperty(methodName); this.lazyLoader.remove(property); } else if (PropertyNamer.isGetter(methodName)) { property = PropertyNamer.methodToProperty(methodName); if (this.lazyLoader.hasLoader(property)) { this.lazyLoader.load(property); } } } else { this.lazyLoader.loadAll(); } } }
return methodProxy.invoke(enhanced, args); } catch (Throwable var10) { throw ExceptionUtil.unwrapThrowable(var10); } } } }
|