Mybatis-懒加载代理源码解析

Mybatis3.5.1源码分析

  1. Mybatis-SqlSessionFactoryBuilder,XMLConfigBuilder,XPathParser源码解析
  2. Mybatis-Configuration源码解析
  3. Mybatis-事务对象源码解析
  4. Mybatis-数据源源码解析
  5. Mybatis缓存策略源码解析
  6. Mybatis-DatabaseIdProvider源码解析
  7. Mybatis-TypeHandler源码解析
  8. Mybatis-Reflector源码解析
  9. Mybatis-ObjectFactory,ObjectWrapperFactory源码分析
  10. Mybatis-Mapper各类标签封装类源码解析
  11. Mybatis-XMLMapperBuilder,XMLStatmentBuilder源码分析
  12. Mybatis-MapperAnnotationBuilder源码分析
  13. [Mybatis-MetaObject,MetaClass源码解析]https://www.jianshu.com/p/f51fa552f30a)
  14. Mybatis-LanguageDriver源码解析
  15. Mybatis-SqlSource源码解析
  16. Mybatis-SqlNode源码解析
  17. Mybatis-KeyGenerator源码解析
  18. Mybatis-Executor源码解析
  19. Mybatis-ParameterHandler源码解析
  20. Mybatis-StatementHandler源码解析
  21. Mybatis-DefaultResultSetHandler(一)源码解析
  22. Mybatis-DefaultResultSetHandler(二)源码解析
  23. Mybatis-ResultHandler,Cursor,RowBounds 源码分析
  24. Mybatis-MapperProxy源码解析
  25. Mybatis-SqlSession源码解析
  26. Mybatis-Interceptor源码解析

ProxyFactory

/**
 *    Copyright 2009-2019 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.executor.loader;

import java.util.List;
import java.util.Properties;

import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.session.Configuration;

/**
* 懒加载代理工厂
 * @author Eduardo Macarron
 */
public interface ProxyFactory {

  /**
   * 用于配置属性,用于使用者自定义实现类的时候进行扩展
   * @param properties 属性集
   */
  void setProperties(Properties properties);

  /**
   * 创建代理对象
   * @param target 结果对象
   * @param lazyLoader 用来表示需要懒加载的属性集,本质是一个HashMap
   * @param configuration Mybatis全局配置信息
   * @param objectFactory 对象工厂
   * @param constructorArgTypes 构造函数参数类型集合
   * @param constructorArgs 构造函数参数集合
   * @return 代理对象
   */
  Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);

}

CglibProxyFactory

/**
 *    Copyright 2009-2018 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.executor.loader.cglib;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import org.apache.ibatis.executor.loader.AbstractEnhancedDeserializationProxy;
import org.apache.ibatis.executor.loader.AbstractSerialStateHolder;
import org.apache.ibatis.executor.loader.ProxyFactory;
import org.apache.ibatis.executor.loader.ResultLoaderMap;
import org.apache.ibatis.executor.loader.WriteReplaceInterface;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.reflection.ExceptionUtil;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.property.PropertyCopier;
import org.apache.ibatis.reflection.property.PropertyNamer;
import org.apache.ibatis.session.Configuration;

/**
 * Cglib懒加载代理工厂
 * @author Clinton Begin
 */
public class CglibProxyFactory implements ProxyFactory {

  /**
   * finalize 方法名
   */
  private static final String FINALIZE_METHOD = "finalize";
  /**
   * writeReplace 方法名
   */
  private static final String WRITE_REPLACE_METHOD = "writeReplace";

  public CglibProxyFactory() {
    //检查是否存在cglib的包
    try {
      Resources.classForName("net.sf.cglib.proxy.Enhancer");
    } catch (Throwable e) {
      throw new IllegalStateException("Cannot enable lazy loading because CGLIB is not available. Add CGLIB to your classpath.", e);
    }
  }

  /**
   *
   * @param target 结果对象
   * @param lazyLoader 用来表示需要懒加载的属性集,本质是一个HashMap
   * @param configuration Mybatis全局配置信息
   * @param objectFactory 对象工厂
   * @param constructorArgTypes 构造函数参数类型集合
   * @param constructorArgs 构造函数参数集合
   * @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);
  }

  /**
   * 创建反序列化代理对象
   * @param target 结果对象
   * @param unloadedProperties 未加载的属性集
   * @param objectFactory 对象工厂
   * @param constructorArgTypes 构造函数参数类型集合
   * @param constructorArgs 构造函数参数集合
   * @return 反序列化代理对象
   */
  public Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    //创建结果对象代理对象
    return EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
  }

  @Override
  public void setProperties(Properties properties) {
      // Not Implemented
  }

  /**
   * 创建代理对象
   * @param type 结果对象类型
   * @param callback 增强结果对象代理实现类
   * @param constructorArgTypes 构造函数参数类型数组
   * @param constructorArgs 构造函数参数数组
   * @return 代理对象
   */
  static Object crateProxy(Class<?> type, Callback callback, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    //CGLIB的代理构建器
    Enhancer enhancer = new Enhancer();
    //设置单一回调对象,在调用中拦截对目标方法的调用
    enhancer.setCallback(callback);
    //设置代理目标
    enhancer.setSuperclass(type);
    try {
      //获取结果对象类型的WriteReplace方法
      type.getDeclaredMethod(WRITE_REPLACE_METHOD);
      // ObjectOutputStream will call writeReplace of objects returned by writeReplace
      //如果可以打印出log
      if (LogHolder.log.isDebugEnabled()) {
        LogHolder.log.debug(WRITE_REPLACE_METHOD + " method was found on bean " + type + ", make sure it returns this");
      }
    } catch (NoSuchMethodException e) {
      //如果不存在WriteReplace方法时,让子类继承WriteReplaceInterface接口
      enhancer.setInterfaces(new Class[]{WriteReplaceInterface.class});
    } catch (SecurityException e) {
      // nothing to do here
    }
    Object enhanced;

    //如果构造函数参数类型集合为空
    if (constructorArgTypes.isEmpty()) {
      //使用无参构造方法创建代理
      enhanced = enhancer.create();
    } else {
      //将构造函数参数类型集合转换成构造函数参数类型数组
      Class<?>[] typesArray = constructorArgTypes.toArray(new Class[constructorArgTypes.size()]);
      //将构造函数参数集合转换成构造函数参数数组
      Object[] valuesArray = constructorArgs.toArray(new Object[constructorArgs.size()]);
      //创建结果对象的代理对象并赋值给enhanced
      enhanced = enhancer.create(typesArray, valuesArray);
    }
    return enhanced;
  }

  /**
   * 增强结果对象代理实现
   */
  private static class EnhancedResultObjectProxyImpl implements MethodInterceptor {
    /**
     * 结果对象类型
     */
    private final Class<?> type;
    /**
     * 用来表示需要懒加载的属性集,本质是一个HashMap
     */
    private final ResultLoaderMap lazyLoader;
    /**
     * 对应于configuration.isAggressiveLazyLoading();当开启时,任何方法的调用都会加载该对象的所有属性。
     * 否则,每个属性会按需加载(参考 lazyLoadTriggerMethods)。默认为false (在 3.4.1 及之前的版本默认值为 true)
     */
    private final boolean aggressive;
    /**
     * 指定哪个对象的方法触发一次延迟加载。默认方法为:equals,clone,hashCode,toString
     */
    private final Set<String> lazyLoadTriggerMethods;
    /**
     * 对象工厂
     */
    private final ObjectFactory objectFactory;
    /**
     * 构造函数参数类型数组
     */
    private final List<Class<?>> constructorArgTypes;
    /**
     * 构造函数参数数组
     */
    private final List<Object> constructorArgs;

    /**
     * 增强结果对象代理实现类
     * @param type 结果对象类型
     * @param lazyLoader 用来表示需要懒加载的属性集,本质是一个HashMap
     * @param configuration  Mybatis全局配置信息
     * @param objectFactory 对象工厂
     * @param constructorArgTypes 构造函数参数类型数组
     * @param constructorArgs 构造函数参数数组
     */
    private EnhancedResultObjectProxyImpl(Class<?> type, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
      this.type = type;
      this.lazyLoader = lazyLoader;
      // AggressiveLazyLoading: 当开启时,任何方法的调用都会加载该对象的所有属性。
      // 否则,每个属性会按需加载(参考 lazyLoadTriggerMethods)。默认为false (在 3.4.1 及之前的版本默认值为 true)
      this.aggressive = configuration.isAggressiveLazyLoading();
      //LazyLoadTriggerMethod:指定哪个对象的方法触发一次延迟加载。默认方法为:equals,clone,hashCode,toString
      this.lazyLoadTriggerMethods = configuration.getLazyLoadTriggerMethods();
      this.objectFactory = objectFactory;
      this.constructorArgTypes = constructorArgTypes;
      this.constructorArgs = constructorArgs;
    }

    /**
     * 创建代理对象
     * @param target 结果对象
     * @param lazyLoader 用来表示需要懒加载的属性集,本质是一个HashMap
     * @param configuration Mybatis全局配置信息
     * @param objectFactory 对象工厂
     * @param constructorArgTypes 构造函数参数类型集合
     * @param constructorArgs 构造函数参数集合
     * @return 代理对象
     */
    public static Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
      //获取结果对象类型
      final Class<?> type = target.getClass();
      //新建一个增强结果对象代理实现类对象
      EnhancedResultObjectProxyImpl callback = new EnhancedResultObjectProxyImpl(type, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
      //创建代理对象
      Object enhanced = crateProxy(type, callback, constructorArgTypes, constructorArgs);
      //将type 的属性值复制到enhanced中
      PropertyCopier.copyBeanProperties(type, target, enhanced);
      return enhanced;
    }

    /**
     * 拦截回调
     * @param enhanced 由Javassist动态生成的代理类实例
     * @param method  当前要调用的方法
     * @param methodProxy JavaAssist获取的进程,是修改后的类方法
     * @param args 参数值列表
     * @return 从代理实例的方法调用返回的值
     */
    @Override
    public Object intercept(Object enhanced, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
      //获取当前要调用的方法名
      final String methodName = method.getName();
      try {
        //同步加锁,防止在多线程情况下,重复加载结果对象属性
        synchronized (lazyLoader) {
          //如果当前要调用的方法名是WriteReplace
          if (WRITE_REPLACE_METHOD.equals(methodName)) {
            Object original;
            //如果构造函数参数类型集合为空
            if (constructorArgTypes.isEmpty()) {
              //使用无参构造函数创建结果对象
              original = objectFactory.create(type);
            } else {
              //使用对应constructorArgTypes的构造函数创建结果对象
              original = objectFactory.create(type, constructorArgTypes, constructorArgs);
            }
            //将enhanced的属性值复制到original中
            PropertyCopier.copyBeanProperties(type, enhanced, original);
            //如果需要懒加载的属性集不是空集合
            if (lazyLoader.size() > 0) {
              //新建一个Cglib序列化状态持有者对象
              return new CglibSerialStateHolder(original, lazyLoader.getProperties(), objectFactory, constructorArgTypes, constructorArgs);
              //如果没有需要懒加载的属性
            } else {
              //返回原始对象
              return original;
            }
            //如果不是writeReplace方法
          } else {
            //如果需要懒加载的属性集不是空集合 且 当前要调用的方法名不是finalize
            if (lazyLoader.size() > 0 && !FINALIZE_METHOD.equals(methodName)) {
              //如果设置了任何方法的调用都会加载该对象的所有属性 或者 指定触发一次延迟加载的方法
              if (aggressive || lazyLoadTriggerMethods.contains(methodName)) {
                //执行对 加载器映射队列的所有元素 的懒加载查询
                lazyLoader.loadAll();
                //如是setter方法
              } else if (PropertyNamer.isSetter(methodName)) {
                //获取methodName对应的属性名
                final String property = PropertyNamer.methodToProperty(methodName);
                //移除该属性的懒加载器,因为调用该属性的setter方法就意味该属性重新赋值,所以不需要再加载
                lazyLoader.remove(property);
                //如果是getter方法
              } else if (PropertyNamer.isGetter(methodName)) {
                //获取methodName对应的属性名
                final String property = PropertyNamer.methodToProperty(methodName);
                //如果存在property对应的懒加载器
                if (lazyLoader.hasLoader(property)) {
                  //执行对 property 的懒加载查询
                  lazyLoader.load(property);
                }
              }
            }
          }
        }
        //否则执行代理方法
        return methodProxy.invokeSuper(enhanced, args);
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    }
  }

  /**
   * 增强反序列代理接口实现类
   */
  private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy implements MethodInterceptor {

    /**
     *
     * @param type 接口对象类型
     * @param unloadedProperties 未加载属性集
     * @param objectFactory 对象工厂
     * @param constructorArgTypes 构造函数参数类型集合
     * @param constructorArgs 构造函数参数集合
     */
    private EnhancedDeserializationProxyImpl(Class<?> type, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
            List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
      super(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
    }

    /**
     * 创建代理对象
     * @param target 结果对象
     * @param unloadedProperties 未加载属性集
     * @param objectFactory 对象工厂
     * @param constructorArgTypes 构造函数参数类型集合
     * @param constructorArgs 构造函数参数集合
     * @return 代理对象
     */
    public static Object createProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
            List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
      //获取结果对象类
      final Class<?> type = target.getClass();
      //新建一个增强反序列化代理实现类对象
      EnhancedDeserializationProxyImpl callback = new EnhancedDeserializationProxyImpl(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
      //创建代理对象
      Object enhanced = crateProxy(type, callback, constructorArgTypes, constructorArgs);
      //将target的属性值复制到enhanced中
      PropertyCopier.copyBeanProperties(type, target, enhanced);
      return enhanced;
    }

    /**
     * 拦截回调
     * @param enhanced 由Cglib动态生成的代理类实例
     * @param method  当前要调用的方法
     * @param methodProxy Cglib获取的进程,是修改后的类方法
     * @param args 参数值列表
     * @return 从代理实例的方法调用返回的值
     */
    @Override
    public Object intercept(Object enhanced, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
      //执行AbstractEnhancedDeserializationProxy的invoke方法,得到代理类对象实例赋值给o
      final Object o = super.invoke(enhanced, method, args);
      //如果o是AbstractSerialStateHolder的子类,返回o;否则执行代理方法
      return o instanceof AbstractSerialStateHolder ? o : methodProxy.invokeSuper(o, args);
    }

    /**
     * 新建一个序列化转换持有者对象
     * @param userBean 结果对象
     * @param unloadedProperties 未加载属性集
     * @param objectFactory 对象工厂
     * @param constructorArgTypes 构造函数参数类型集合
     * @param constructorArgs 构造函数参数集合
     * @return 序列化转换持有者对象
     */
    @Override
    protected AbstractSerialStateHolder newSerialStateHolder(Object userBean, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
            List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
      //新建一个Javassist序列化状态持有者对象
      return new CglibSerialStateHolder(userBean, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
    }
  }

  private static class LogHolder {
    private static final Log log = LogFactory.getLog(CglibProxyFactory.class);
  }

}

JavassistProxyFactory

/**
 *    Copyright 2009-2018 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.executor.loader.javassist;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.Proxy;
import javassist.util.proxy.ProxyFactory;

import org.apache.ibatis.executor.ExecutorException;
import org.apache.ibatis.executor.loader.AbstractEnhancedDeserializationProxy;
import org.apache.ibatis.executor.loader.AbstractSerialStateHolder;
import org.apache.ibatis.executor.loader.ResultLoaderMap;
import org.apache.ibatis.executor.loader.WriteReplaceInterface;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.reflection.ExceptionUtil;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.property.PropertyCopier;
import org.apache.ibatis.reflection.property.PropertyNamer;
import org.apache.ibatis.session.Configuration;

/**
 * Javassist代理工厂
 * @author Eduardo Macarron
 */
public class JavassistProxyFactory implements org.apache.ibatis.executor.loader.ProxyFactory {

  /**
   * finalize 方法名
   */
  private static final String FINALIZE_METHOD = "finalize";
  /**
   * writeReplace 方法名
   */
  private static final String WRITE_REPLACE_METHOD = "writeReplace";

  public JavassistProxyFactory() {
    //检查是否存在javassist的包
    try {
      Resources.classForName("javassist.util.proxy.ProxyFactory");
    } catch (Throwable e) {
      throw new IllegalStateException("Cannot enable lazy loading because Javassist is not available. Add Javassist to your classpath.", e);
    }
  }

  /**
   * 创建代理对象
   * @param target 结果对象
   * @param lazyLoader 用来表示需要懒加载的属性集,本质是一个HashMap
   * @param configuration Mybatis全局配置信息
   * @param objectFactory 对象工厂
   * @param constructorArgTypes 构造函数参数类型集合
   * @param constructorArgs 构造函数参数集合
   * @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);
  }

  /**
   * 创建反序列化代理对象
   * @param target 结果对象
   * @param unloadedProperties 未加载的属性集
   * @param objectFactory 对象工厂
   * @param constructorArgTypes 构造函数参数类型集合
   * @param constructorArgs 构造函数参数集合
   * @return 反序列化代理对象
   */
  public Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    //创建结果对象代理对象
    return EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
  }

  @Override
  public void setProperties(Properties properties) {
      // Not Implemented
  }

  /**
   * 创建代理对象
   * @param type 结果对象类型
   * @param callback 增强结果对象代理实现类
   * @param constructorArgTypes 构造函数参数类型数组
   * @param constructorArgs 构造函数参数数组
   * @return 代理对象
   */
  static Object crateProxy(Class<?> type, MethodHandler callback, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    //javassist的代理工厂
    ProxyFactory enhancer = new ProxyFactory();
    //设置需要创建子类的父类
    enhancer.setSuperclass(type);

    try {
      //获取结果对象类型的WriteReplace方法
      type.getDeclaredMethod(WRITE_REPLACE_METHOD);
      // ObjectOutputStream will call writeReplace of objects returned by writeReplace
      //如果可以打印出log
      if (LogHolder.log.isDebugEnabled()) {
        //打印log,通知WriteReplace方法在type找到了
        LogHolder.log.debug(WRITE_REPLACE_METHOD + " method was found on bean " + type + ", make sure it returns this");
      }
    } catch (NoSuchMethodException e) {
      //如果不存在WriteReplace方法时,让子类继承WriteReplaceInterface接口
      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 {
      //创建结果对象的代理对象并赋值给enhanced
      enhanced = enhancer.create(typesArray, valuesArray);
    } catch (Exception e) {
      throw new ExecutorException("Error creating lazy proxy.  Cause: " + e, e);
    }
    //定义一个拦截器。在调用目标方法时,Javassist会回调MethodHandler接口方法拦截,
    //来实现你自己的代理逻辑,类似于JDK中的InvocationHandler接口。
    ((Proxy) enhanced).setHandler(callback);
    return enhanced;
  }

  /**
   * 增强结果对象代理实现类
   */
  private static class EnhancedResultObjectProxyImpl implements MethodHandler {

    /**
     * 结果对象类型
     */
    private final Class<?> type;
    /**
     * 用来表示需要懒加载的属性集,本质是一个HashMap
     */
    private final ResultLoaderMap lazyLoader;

    /**
     * 对应于configuration.isAggressiveLazyLoading();当开启时,任何方法的调用都会加载该对象的所有属性。
     * 否则,每个属性会按需加载(参考 lazyLoadTriggerMethods)。默认为false (在 3.4.1 及之前的版本默认值为 true)
     */
    private final boolean aggressive;
    /**
     * 指定哪个对象的方法触发一次延迟加载。默认方法为:equals,clone,hashCode,toString
     */
    private final Set<String> lazyLoadTriggerMethods;
    /**
     * 对象工厂
     */
    private final ObjectFactory objectFactory;
    /**
     * 构造函数参数类型数组
     */
    private final List<Class<?>> constructorArgTypes;
    /**
     * 构造函数参数数组
     */
    private final List<Object> constructorArgs;

    /**
     *
     * @param type 结果对象类型
     * @param lazyLoader 用来表示需要懒加载的属性集,本质是一个HashMap
     * @param configuration Mybatis全局配置信息
     * @param objectFactory 对象工厂
     * @param constructorArgTypes 构造函数参数类型数组
     * @param constructorArgs 构造函数参数数组
     */
    private EnhancedResultObjectProxyImpl(Class<?> type, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
      this.type = type;
      this.lazyLoader = lazyLoader;
      // AggressiveLazyLoading: 当开启时,任何方法的调用都会加载该对象的所有属性。
      // 否则,每个属性会按需加载(参考 lazyLoadTriggerMethods)。默认为false (在 3.4.1 及之前的版本默认值为 true)
      this.aggressive = configuration.isAggressiveLazyLoading();
      //LazyLoadTriggerMethod:指定哪个对象的方法触发一次延迟加载。默认方法为:equals,clone,hashCode,toString
      this.lazyLoadTriggerMethods = configuration.getLazyLoadTriggerMethods();
      this.objectFactory = objectFactory;
      this.constructorArgTypes = constructorArgTypes;
      this.constructorArgs = constructorArgs;
    }

    /**
     * 创建代理对象
     * @param target 结果对象
     * @param lazyLoader 用来表示需要懒加载的属性集,本质是一个HashMap
     * @param configuration Mybatis全局配置信息
     * @param objectFactory 对象工厂
     * @param constructorArgTypes 构造函数参数类型集合
     * @param constructorArgs 构造函数参数集合
     * @return 代理对象
     */
    public static Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
      //获取结果对象类型
      final Class<?> type = target.getClass();
      //新建一个增强结果对象代理实现类对象
      EnhancedResultObjectProxyImpl callback = new EnhancedResultObjectProxyImpl(type, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
      //创建代理对象
      Object enhanced = crateProxy(type, callback, constructorArgTypes, constructorArgs);
      //将type 的属性值复制到enhanced中
      PropertyCopier.copyBeanProperties(type, target, enhanced);
      return enhanced;
    }

    /**
     * 拦截回调
     * @param enhanced 由Javassist动态生成的代理类实例
     * @param method  当前要调用的方法
     * @param methodProxy JavaAssist获取的进程,是修改后的类方法
     * @param args 参数值列表
     * @return 从代理实例的方法调用返回的值
     */
    @Override
    public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable {
      //获取当前要调用的方法名
      final String methodName = method.getName();
      try {
        //同步加锁,防止在多线程情况下,重复加载结果对象属性
        synchronized (lazyLoader) {
          //如果当前要调用的方法名是WriteReplace
          if (WRITE_REPLACE_METHOD.equals(methodName)) {
            Object original;
            //如果构造函数参数类型集合为空
            if (constructorArgTypes.isEmpty()) {
              //使用无参构造函数创建结果对象
              original = objectFactory.create(type);
            } else {
              //使用对应constructorArgTypes的构造函数创建结果对象
              original = objectFactory.create(type, constructorArgTypes, constructorArgs);
            }
            //将enhanced的属性值复制到original中
            PropertyCopier.copyBeanProperties(type, enhanced, original);
            //如果需要懒加载的属性集不是空集合
            if (lazyLoader.size() > 0) {
              //新建一个Javassist序列化状态持有者对象
              return new JavassistSerialStateHolder(original, lazyLoader.getProperties(), objectFactory, constructorArgTypes, constructorArgs);
              //如果没有需要懒加载的属性
            } else {
              //返回原始对象
              return original;
            }
            ////如果不是writeReplace方法
          } else {
            //如果需要懒加载的属性集不是空集合 且 当前要调用的方法名不是finalize
            if (lazyLoader.size() > 0 && !FINALIZE_METHOD.equals(methodName)) {
              //如果设置了任何方法的调用都会加载该对象的所有属性 或者 指定触发一次延迟加载的方法
              if (aggressive || lazyLoadTriggerMethods.contains(methodName)) {
                //执行对 加载器映射队列的所有元素 的懒加载查询
                lazyLoader.loadAll();
                //如是setter方法
              } else if (PropertyNamer.isSetter(methodName)) {
                //获取methodName对应的属性名
                final String property = PropertyNamer.methodToProperty(methodName);
                //移除该属性的懒加载器,因为调用该属性的setter方法就意味该属性重新赋值,所以不需要再加载
                lazyLoader.remove(property);
                //如果是getter方法
              } else if (PropertyNamer.isGetter(methodName)) {
                //获取methodName对应的属性名
                final String property = PropertyNamer.methodToProperty(methodName);
                //如果存在property对应的懒加载器
                if (lazyLoader.hasLoader(property)) {
                  //执行对 property 的懒加载查询
                  lazyLoader.load(property);
                }
              }
            }
          }
        }
        //否则执行代理方法
        return methodProxy.invoke(enhanced, args);
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    }
  }

  /**
   * 增强反序列代理接口实现类
   */
  private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy implements MethodHandler {

    /**
     *
     * @param type 接口对象类型
     * @param unloadedProperties 未加载属性集
     * @param objectFactory 对象工厂
     * @param constructorArgTypes 构造函数参数类型集合
     * @param constructorArgs 构造函数参数集合
     */
    private EnhancedDeserializationProxyImpl(Class<?> type, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
            List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
      super(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
    }

    /**
     * 创建代理对象
     * @param target 结果对象
     * @param unloadedProperties 未加载属性集
     * @param objectFactory 对象工厂
     * @param constructorArgTypes 构造函数参数类型集合
     * @param constructorArgs 构造函数参数集合
     * @return 代理对象
     */
    public static Object createProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
            List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
      //获取结果对象类
      final Class<?> type = target.getClass();
      //新建一个增强反序列化代理实现类对象
      EnhancedDeserializationProxyImpl callback = new EnhancedDeserializationProxyImpl(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
      //创建代理对象
      Object enhanced = crateProxy(type, callback, constructorArgTypes, constructorArgs);
      //将target的属性值复制到enhanced中
      PropertyCopier.copyBeanProperties(type, target, enhanced);
      return enhanced;
    }

    /**
     * 拦截回调
     * @param enhanced 由Javassist动态生成的代理类实例
     * @param method  当前要调用的方法
     * @param methodProxy JavaAssist获取的进程,是修改后的类方法
     * @param args 参数值列表
     * @return 从代理实例的方法调用返回的值
     */
    @Override
    public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable {
      //执行AbstractEnhancedDeserializationProxy的invoke方法,得到代理类对象实例赋值给o
      final Object o = super.invoke(enhanced, method, args);
      //如果o是AbstractSerialStateHolder的子类,返回o;否则执行代理方法
      return o instanceof AbstractSerialStateHolder ? o : methodProxy.invoke(o, args);
    }

    /**
     * 新建一个序列化转换持有者对象
     * @param userBean 结果对象
     * @param unloadedProperties 未加载属性集
     * @param objectFactory 对象工厂
     * @param constructorArgTypes 构造函数参数类型集合
     * @param constructorArgs 构造函数参数集合
     * @return 序列化转换持有者对象
     */
    @Override
    protected AbstractSerialStateHolder newSerialStateHolder(Object userBean, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
            List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
      //新建一个Javassist序列化状态持有者对象
      return new JavassistSerialStateHolder(userBean, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
    }
  }

  private static class LogHolder {
    private static final Log log = LogFactory.getLog(JavassistProxyFactory.class);
  }

}

AbstractEnhancedDeserializationProxy

/**
 *    Copyright 2009-2017 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.executor.loader;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.ibatis.executor.ExecutorException;

import org.apache.ibatis.reflection.ExceptionUtil;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.property.PropertyCopier;
import org.apache.ibatis.reflection.property.PropertyNamer;

/**
 * 抽象增强反序列化代理
 * @author Clinton Begin
 */
public abstract class AbstractEnhancedDeserializationProxy {

  /**
   * finalize方法名
   */
  protected static final String FINALIZE_METHOD = "finalize";
  /**
   * writeReplace 方法名
   */
  protected static final String WRITE_REPLACE_METHOD = "writeReplace";
  /**
   * 结果对象类型
   */
  private final Class<?> type;
  /**
   * 未加载属性集
   */
  private final Map<String, ResultLoaderMap.LoadPair> unloadedProperties;
  /**
   * 对象工厂
   */
  private final ObjectFactory objectFactory;
  /**
   * 构造函数参数类型数组
   */
  private final List<Class<?>> constructorArgTypes;
  /**
   * 构造函数参数对象
   */
  private final List<Object> constructorArgs;
  /**
   * 正在重新加载属性锁
   */
  private final Object reloadingPropertyLock;
  /**
   * 是否正在重新加载属性
   */
  private boolean reloadingProperty;

  /**
   *
   * @param type 结果对象类型
   * @param unloadedProperties 未加载属性集
   * @param objectFactory 对象工厂
   * @param constructorArgTypes 构造函数参数类型集合
   * @param constructorArgs 构造函数参数集合
   */
  protected AbstractEnhancedDeserializationProxy(Class<?> type, Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
          ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    this.type = type;
    this.unloadedProperties = unloadedProperties;
    this.objectFactory = objectFactory;
    this.constructorArgTypes = constructorArgTypes;
    this.constructorArgs = constructorArgs;
    this.reloadingPropertyLock = new Object();
    this.reloadingProperty = false;
  }

  /**
   * 拦截回调
   * @param enhanced 代理类对象实例
   * @param method 当前要调用的方法
   * @param args 参数对象数组
   * @return 代理类对象实例
   */
  public final Object invoke(Object enhanced, Method method, Object[] args) throws Throwable {
    //获取当前要调用的方法名
    final String methodName = method.getName();
    try {
      //如果当前要调用的方法名是WriteReplace
      if (WRITE_REPLACE_METHOD.equals(methodName)) {
        final Object original;
        //如果构造函数参数类型集合为空
        if (constructorArgTypes.isEmpty()) {
          //使用无参构造函数创建结果对象
          original = objectFactory.create(type);
        } else {
          //使用对应constructorArgTypes的构造函数创建结果对象
          original = objectFactory.create(type, constructorArgTypes, constructorArgs);
        }
        //将enhanced的属性值复制到original中
        PropertyCopier.copyBeanProperties(type, enhanced, original);
        //新建一个序列化转换持有者对象
        return this.newSerialStateHolder(original, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
      } else {
        //同步加锁,防止在多线程情况下,重复加载结果对象属性
        synchronized (this.reloadingPropertyLock) {
          //如果当前要调用的方法名不是WriteReplace 且 当前调用方法名是属性方法 且 不是正在重新加载属性
          if (!FINALIZE_METHOD.equals(methodName) && PropertyNamer.isProperty(methodName) && !reloadingProperty) {
            //取出methodName方法名的属性名
            final String property = PropertyNamer.methodToProperty(methodName);
            //将属性名转换成大写
            final String propertyKey = property.toUpperCase(Locale.ENGLISH);
            //如果proertypeKey属于未加载的属性集中的属性
            if (unloadedProperties.containsKey(propertyKey)) {
              //获取propertyKey对应的LoadPair对象
              final ResultLoaderMap.LoadPair loadPair = unloadedProperties.remove(propertyKey);
              //如果loadPair不为null
              if (loadPair != null) {
                try {
                  //设置正在重新加载属性为true
                  reloadingProperty = true;
                  //执行懒加载查询,获取数据并且赋值到enhanced
                  loadPair.load(enhanced);
                } finally {
                  //还原设置正在重新加载属性为false
                  reloadingProperty = false;
                }
              } else {
                /* I'm not sure if this case can really happen or is just in tests -
                 * we have an unread property but no loadPair to load it.
                 * 译文:
                 * 我不确定这种情况下能发生或只是在测试中 - 我们有一个未加载的属性但是没有LoadPair对象去加载它
                 * */
                //抛出异常
                throw new ExecutorException("An attempt has been made to read a not loaded lazy property '"
                        + property + "' of a disconnected object");
              }
            }
          }

          return enhanced;
        }
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
  }

  /**
   * 新建一个序列化转换持有者对象
   * @param userBean 结果对象
   * @param unloadedProperties 未加载属性集
   * @param objectFactory 对象工厂
   * @param constructorArgTypes 构造函数参数类型集合
   * @param constructorArgs 构造函数参数集合
   * @return 序列化转换持有者对象
   */
  protected abstract AbstractSerialStateHolder newSerialStateHolder(
          Object userBean,
          Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
          ObjectFactory objectFactory,
          List<Class<?>> constructorArgTypes,
          List<Object> constructorArgs);

}

AbstractSerialStateHolder

/**
 *    Copyright 2009-2018 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.executor.loader;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.ObjectStreamException;
import java.io.StreamCorruptedException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.reflection.factory.ObjectFactory;

/**
 * 抽象序列化转换持有者
 * <p>
 *     Externalizable:继承Serializable接口,可完成部分属性的序列化
 * </p>
 * @author Eduardo Macarron
 * @author Franta Mejta
 */
public abstract class AbstractSerialStateHolder implements Externalizable {

  private static final long serialVersionUID = 8940388717901644661L;
  private static final ThreadLocal<ObjectOutputStream> stream = new ThreadLocal<>();
  private byte[] userBeanBytes = new byte[0];
  /**
   * 结果对象
   */
  private Object userBean;
  /**
   * 未加载的属性集
   * <p>
   *     LoadPair:对于单个属性懒加载信息的封装,最重要的就是其load方法用来加载属性
   * </p>
   */
  private Map<String, ResultLoaderMap.LoadPair> unloadedProperties;
  /**
   * 对象工厂
   */
  private ObjectFactory objectFactory;
  /**
   * 构造函数参数类型数组
   */
  private Class<?>[] constructorArgTypes;
  /**
   * 构造函数参数数组
   */
  private Object[] constructorArgs;

  public AbstractSerialStateHolder() {
  }

  /**
   *
   * @param userBean 结果对象
   * @param unloadedProperties 未加载的属性集
   * @param objectFactory 对象工厂
   * @param constructorArgTypes 构造函数参数类型集合
   * @param constructorArgs 构造函数参数集合
   */
  public AbstractSerialStateHolder(
          final Object userBean,
          final Map<String, ResultLoaderMap.LoadPair> unloadedProperties,
          final ObjectFactory objectFactory,
          List<Class<?>> constructorArgTypes,
          List<Object> constructorArgs) {
    this.userBean = userBean;
    this.unloadedProperties = new HashMap<>(unloadedProperties);
    this.objectFactory = objectFactory;
    //将构造函数参数类型集合转换成构造函数参数类型数组
    this.constructorArgTypes = constructorArgTypes.toArray(new Class<?>[constructorArgTypes.size()]);
    //将构造函数参数集合转换成构造函数参数数组
    this.constructorArgs = constructorArgs.toArray(new Object[constructorArgs.size()]);
  }

  /**
   * 序列化
   * @param out 对象输出流
   */
  @Override
  public final void writeExternal(final ObjectOutput out) throws IOException {
    //定义表示第一轮标记,设置为false
    boolean firstRound = false;
    //新建一个字节数组输出流
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    //获取对象输出流
    ObjectOutputStream os = stream.get();
    //如果os为null
    if (os == null) {
      //新建一个对象输出流对象装饰baos
      os = new ObjectOutputStream(baos);
      //将第一轮标记设置为true
      firstRound = true;
      //将输出流添加到stream中
      stream.set(os);
    }
    //将结果对象写进对象流
    os.writeObject(this.userBean);
    //将未加载属性集写进对象流
    os.writeObject(this.unloadedProperties);
    //将对象工厂写进对象流
    os.writeObject(this.objectFactory);
    //将构造函数参数类型数组写进对象流
    os.writeObject(this.constructorArgTypes);
    //将构造函数参数数组写进对象流
    os.writeObject(this.constructorArgs);

    //取出字节数组
    final byte[] bytes = baos.toByteArray();
    //将字节数组写进out
    out.writeObject(bytes);

    //如果是第一轮
    if (firstRound) {
      //移除存放在stream的输出流
      stream.remove();
    }
  }

  /**
   * 反序列化
   * @param in 对象输入流
   */
  @Override
  public final void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
    //读取流中的对象
    final Object data = in.readObject();
    //如果data是数组
    if (data.getClass().isArray()) {
      //将data强转成byte[]赋值给userBeanBytes
      this.userBeanBytes = (byte[]) data;
    } else {
      //将data赋值给userBean
      this.userBean = data;
    }
  }

  @SuppressWarnings("unchecked")
  protected final Object readResolve() throws ObjectStreamException {
    /* Second run */
    //如果userBean不为null且userBeanBytes为空数组
    if (this.userBean != null && this.userBeanBytes.length == 0) {
      //直接返回userBena
      return this.userBean;
    }

    //新建一个反序列化对象白名单控制输入流对象对userBeanBytes进行解析
    /* First run */
    try (ObjectInputStream in = new LookAheadObjectInputStream(new ByteArrayInputStream(this.userBeanBytes))) {
      //获取结果对象
      this.userBean = in.readObject();
      //获取未加载的属性集
      this.unloadedProperties = (Map<String, ResultLoaderMap.LoadPair>) in.readObject();
      //获取对象工厂
      this.objectFactory = (ObjectFactory) in.readObject();
      //获取构造函数参数类型数组
      this.constructorArgTypes = (Class<?>[]) in.readObject();
      //获取构造函数参数数组
      this.constructorArgs = (Object[]) in.readObject();
    } catch (final IOException ex) {
      throw (ObjectStreamException) new StreamCorruptedException().initCause(ex);
    } catch (final ClassNotFoundException ex) {
      throw (ObjectStreamException) new InvalidClassException(ex.getLocalizedMessage()).initCause(ex);
    }
    //将未加载的属性集添加到一个新的HashMap中
    final Map<String, ResultLoaderMap.LoadPair> arrayProps = new HashMap<>(this.unloadedProperties);
    //将构造函数参数类型数组添加到新的ArrayList中
    final List<Class<?>> arrayTypes = Arrays.asList(this.constructorArgTypes);
    //将构造函数参数数组添加到新的ArrayList中
    final List<Object> arrayValues = Arrays.asList(this.constructorArgs);
    //创建反序列代理对象
    return this.createDeserializationProxy(userBean, arrayProps, objectFactory, arrayTypes, arrayValues);
  }

  /**
   * 创建反序列代理对象
   * @param target 结果对象
   * @param unloadedProperties 未加载属性集
   * @param objectFactory 对象工厂
   * @param constructorArgTypes 构造函数参数类型集合
   * @param constructorArgs 构造函数参数集合
   * @return 反序列代理对象
   */
  protected abstract Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties, ObjectFactory objectFactory,
          List<Class<?>> constructorArgTypes, List<Object> constructorArgs);

  /**
   * 反序列化对象白名单控制输入流
   */
  private static class LookAheadObjectInputStream extends ObjectInputStream {
    /**
     * 黑名单类列表
     */
    private static final List<String> blacklist = Arrays.asList(
        "org.apache.commons.beanutils.BeanComparator",
        "org.apache.commons.collections.functors.InvokerTransformer",
        "org.apache.commons.collections.functors.InstantiateTransformer",
        "org.apache.commons.collections4.functors.InvokerTransformer",
        "org.apache.commons.collections4.functors.InstantiateTransformer",
        "org.codehaus.groovy.runtime.ConvertedClosure",
        "org.codehaus.groovy.runtime.MethodClosure",
        "org.springframework.beans.factory.ObjectFactory",
        "org.springframework.transaction.jta.JtaTransactionManager",
        "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");

    public LookAheadObjectInputStream(InputStream in) throws IOException {
      super(in);
    }

    @Override
    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
      //获取desc的包名+类名
      String className = desc.getName();
      //如果className存在在黑名单类列表中,表示可能有黑客在反序列的时候篡改了字节数据
      if (blacklist.contains(className)) {
        //抛出异常
        throw new InvalidClassException(className, "Deserialization is not allowed for security reasons. "
            + "It is strongly recommended to configure the deserialization filter provided by JDK. "
            + "See http://openjdk.java.net/jeps/290 for the details.");
      }
      return super.resolveClass(desc);
    }
  }
}

PropertyCopier

/**
 *    Copyright 2009-2019 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.reflection.property;

import java.lang.reflect.Field;

import org.apache.ibatis.reflection.Reflector;

/**
 * 属性复制器
 * @author Clinton Begin
 */
public final class PropertyCopier {

  private PropertyCopier() {
    // Prevent Instantiation of Static Class
  }

  /**
   * 将{@code sourceBean} 的属性值复制到{@code destinationBean}中
   * @param type {@code sourceBean}和{@code destinationBean} 都同时继承的类
   * @param sourceBean 原对象
   * @param destinationBean 目标对象
   */
  public static void copyBeanProperties(Class<?> type, Object sourceBean, Object destinationBean) {
    //然后type充当parent
    Class<?> parent = type;
    //只要parent不为null,继续循环
    while (parent != null) {
      //获取类中的所有Field
      final Field[] fields = parent.getDeclaredFields();
      //遍历所有Field
      for (Field field : fields) {
        try {
          try {
            //获取sourceBean的field属性值赋值到destinationBean的Field属性中
            field.set(destinationBean, field.get(sourceBean));
          } catch (IllegalAccessException e) {
            //如果从java安全管理器中获取suppressAccessChecks反射权限是存在的
            if (Reflector.canControlMemberAccessible()) {
              //设置属性为可访问
              field.setAccessible(true);
              //获取sourceBean的field属性值赋值到destinationBean的Field属性中
              field.set(destinationBean, field.get(sourceBean));
            } else {
              //抛出无权限访问异常
              throw e;
            }
          }
        } catch (Exception e) {
          // Nothing useful to do, will only fail on final fields, which will be ignored.
        }
      }
      //获取parent的父类重新赋值给parent
      parent = parent.getSuperclass();
    }
  }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容