日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

mybatis工作原理及流程 mybatis延遲加載原理( 二 )

延遲加載代理對象創(chuàng)建
DefaultResultSetHandler
//#mark 創(chuàng)建結(jié)果對象 private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, ResultLoaderMap lazyLoader, String columnPrefix) throws SQLException { this.useConstructorMappings = false; // reset previous mapping result final List<Class<?>> constructorArgTypes = new ArrayList<Class<?>>(); final List<Object> constructorArgs = new ArrayList<Object>(); //#mark 創(chuàng)建返回的結(jié)果映射的真實(shí)對象 Object resultObject = createResultObject(rsw, resultMap, constructorArgTypes, constructorArgs, columnPrefix); if (resultObject != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) { final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings(); for (ResultMapping propertyMapping : propertyMappings) { // issue gcode #109 && issue #149 判斷屬性有沒配置嵌套查詢 , 如果有就創(chuàng)建代理對象 if (propertyMapping.getNestedQueryId() != null && propertyMapping.isLazy()) { //#mark 創(chuàng)建延遲加載代理對象 resultObject = configuration.getProxyFactory().createProxy(resultObject, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs); break; } } } this.useConstructorMappings = resultObject != null && !constructorArgTypes.isEmpty(); // set current mapping result return resultObject; }代理功能實(shí)現(xiàn)

【mybatis工作原理及流程 mybatis延遲加載原理】由于Javasisst和Cglib的代理實(shí)現(xiàn)基本相同 , 這里主要介紹Javasisst
ProxyFactory接口定義
public interface ProxyFactory {
void setProperties(Properties properties);
/**
* 創(chuàng)建代理
* @param target 目標(biāo)結(jié)果對象
* @param lazyLoader 延遲加載對象
* @param configuration 配置
* @param objectFactory 對象工廠
* @param constructorArgTypes 構(gòu)造參數(shù)類型
* @param constructorArgs 構(gòu)造參數(shù)值
* @return
*/
Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);
}
JavasisstProxyFactory實(shí)現(xiàn)
public class JavassistProxyFactory implements org.apache.ibatis.executor.loader.ProxyFactory {/** * 接口實(shí)現(xiàn) * @param target 目標(biāo)結(jié)果對象 * @param lazyLoader 延遲加載對象 * @param configuration 配置 * @param objectFactory 對象工廠 * @param constructorArgTypes 構(gòu)造參數(shù)類型 * @param constructorArgs 構(gòu)造參數(shù)值 * @return */ @Override public Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { return EnhancedResultObjectProxyImpl.createProxy(target, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs); } //省略.../** * 代理對象實(shí)現(xiàn) , 核心邏輯執(zhí)行 */ private static class EnhancedResultObjectProxyImpl implements MethodHandler {/** * 創(chuàng)建代理對象 * @param type * @param callback * @param constructorArgTypes * @param constructorArgs * @return */ static Object crateProxy(Class<?> type, MethodHandler callback, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) { ProxyFactory enhancer = new ProxyFactory(); enhancer.setSuperclass(type); try { //通過獲取對象方法 , 判斷是否存在該方法 type.getDeclaredMethod(WRITE_REPLACE_METHOD); // ObjectOutputStream will call writeReplace of objects returned by writeReplace if (log.isDebugEnabled()) { log.debug(WRITE_REPLACE_METHOD + " method was found on bean " + type + ", make sure it returns this"); } } catch (NoSuchMethodException e) { //沒找到該方法 , 實(shí)現(xiàn)接口 enhancer.setInterfaces(new Class[]{WriteReplaceInterface.class}); } catch (SecurityException e) { // nothing to do here } Object enhanced; Class<?>[] typesArray = constructorArgTypes.toArray(new Class[constructorArgTypes.size()]); Object[] valuesArray = constructorArgs.toArray(new Object[constructorArgs.size()]); try { //創(chuàng)建新的代理對象 enhanced = enhancer.create(typesArray, valuesArray); } catch (Exception e) { throw new ExecutorException("Error creating lazy proxy. Cause: " + e, e); } //設(shè)置代理執(zhí)行器 ((Proxy) enhanced).setHandler(callback); return enhanced; }/** * 代理對象執(zhí)行 * @param enhanced 原對象 * @param method 原對象方法 * @param methodProxy 代理方法 * @param args 方法參數(shù) * @return * @throws Throwable */ @Override public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable { final String methodName = method.getName(); try { synchronized (lazyLoader) { if (WRITE_REPLACE_METHOD.equals(methodName)) {//忽略暫未找到具體作用 Object original; if (constructorArgTypes.isEmpty()) { original = objectFactory.create(type); } else { original = objectFactory.create(type, constructorArgTypes, constructorArgs); } PropertyCopier.copyBeanProperties(type, enhanced, original); if (lazyLoader.size() > 0) { return new JavassistSerialStateHolder(original, lazyLoader.getProperties(), objectFactory, constructorArgTypes, constructorArgs); } else { return original; } } else { //延遲加載數(shù)量大于0 if (lazyLoader.size() > 0 && !FINALIZE_METHOD.equals(methodName)) { //aggressive 一次加載性所有需要要延遲加載屬性或者包含觸發(fā)延遲加載方法 if (aggressive || lazyLoadTriggerMethods.contains(methodName)) { log.debug("==> laze lod trigger method:" + methodName + ",proxy method:" + methodProxy.getName() + " class:" + enhanced.getClass()); //一次全部加載 lazyLoader.loadAll(); } else if (PropertyNamer.isSetter(methodName)) { //判斷是否為set方法 , set方法不需要延遲加載 final String property = PropertyNamer.methodToProperty(methodName); lazyLoader.remove(property); } else if (PropertyNamer.isGetter(methodName)) { final String property = PropertyNamer.methodToProperty(methodName); if (lazyLoader.hasLoader(property)) { //延遲加載單個(gè)屬性 lazyLoader.load(property); log.debug("load one :" + methodName); } } } } } return methodProxy.invoke(enhanced, args); } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } } }

推薦閱讀