mybatis源码解析四之各大组件

xpath解析xml

public class XPathParser {

  private final Document document;
  //是否开启验证
  private boolean validation;
  //加载本地DTD
  private EntityResolver entityResolver;
  //Properties标签定义值
  private Properties variables;
  private XPath xpath;
}

解析DTD

spring专栏有自定义命名空间解析,就不阐述了

public class XMLMapperEntityResolver implements EntityResolver {

  //指定mybatis-config.xml的DTD
  private static final String IBATIS_CONFIG_SYSTEM = "ibatis-3-config.dtd";
  private static final String IBATIS_MAPPER_SYSTEM = "ibatis-3-mapper.dtd";
  private static final String MYBATIS_CONFIG_SYSTEM = "mybatis-3-config.dtd";
  private static final String MYBATIS_MAPPER_SYSTEM = "mybatis-3-mapper.dtd";

  //指定dtd位置
  private static final String MYBATIS_CONFIG_DTD = "org/apache/ibatis/builder/xml/mybatis-3-config.dtd";
  private static final String MYBATIS_MAPPER_DTD = "org/apache/ibatis/builder/xml/mybatis-3-mapper.dtd";
 @Override
  public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
    try {
      if (systemId != null) {
        String lowerCaseSystemId = systemId.toLowerCase(Locale.ENGLISH);
        //查找sysId指定的DTD文档,并读取
        if (lowerCaseSystemId.contains(MYBATIS_CONFIG_SYSTEM) || lowerCaseSystemId.contains(IBATIS_CONFIG_SYSTEM)) {
          return getInputSource(MYBATIS_CONFIG_DTD, publicId, systemId);
        } else if (lowerCaseSystemId.contains(MYBATIS_MAPPER_SYSTEM) || lowerCaseSystemId.contains(IBATIS_MAPPER_SYSTEM)) {
          return getInputSource(MYBATIS_MAPPER_DTD, publicId, systemId);
        }
      }
      return null;
    } catch (Exception e) {
      throw new SAXException(e.toString());
    }
  }
  }

构造Xpath和document

  public XPathParser(String xml) {
      //构造时,初始化xpath
    commonConstructor(false, null, null);
    this.document = createDocument(new InputSource(new StringReader(xml)));
  }
  private void commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver) {
    this.validation = validation;
    this.entityResolver = entityResolver;
    this.variables = variables;
    XPathFactory factory = XPathFactory.newInstance();
    this.xpath = factory.newXPath();
  }
private Document createDocument(InputSource inputSource) {
    // important: this must only be called AFTER common constructor
    try {

      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
      factory.setValidating(validation);

      factory.setNamespaceAware(false);
      factory.setIgnoringComments(true);
      factory.setIgnoringElementContentWhitespace(false);
      factory.setCoalescing(false);
      factory.setExpandEntityReferences(true);

      DocumentBuilder builder = factory.newDocumentBuilder();
      //设置DTD解析器
      builder.setEntityResolver(entityResolver);
      builder.setErrorHandler(new ErrorHandler() {
        @Override
        public void error(SAXParseException exception) throws SAXException {
          throw exception;
        }

        @Override
        public void fatalError(SAXParseException exception) throws SAXException {
          throw exception;
        }

        @Override
        public void warning(SAXParseException exception) throws SAXException {
          // NOP
        }
      });
      //加载XML
      return builder.parse(inputSource);
    } catch (Exception e) {
      throw new BuilderException("Error creating document instance.  Cause: " + e, e);
    }
  }

解析String

  public String evalString(Object root, String expression) {
    String result = (String) evaluate(expression, root, XPathConstants.STRING);
    //设置节点默认值
    result = PropertyParser.parse(result, variables);
    return result;
  }
  public static String parse(String string, Properties variables) {
    VariableTokenHandler handler = new VariableTokenHandler(variables);
    //指定处理的占位符格式为${}
    GenericTokenParser parser = new GenericTokenParser("${", "}", handler);
    return parser.parse(string);
  }

public class GenericTokenParser {

  //占位符开始标记
  private final String openToken;
  //占位符结束标记
  private final String closeToken;
  //解析占位符
  private final TokenHandler handler;
  
  /**
   * 将text根据前后占位符解析
   * @param text
   * @return
   */
  public String parse(String text) {
    if (text == null || text.isEmpty()) {
      return "";
    }
    // search open token
    //查找第一个开启占位符位置
    int start = text.indexOf(openToken);
    if (start == -1) {
      return text;
    }
    char[] src = text.toCharArray();
    int offset = 0;
    //线程安全,记录占位符的值
    final StringBuilder builder = new StringBuilder();
    StringBuilder expression = null;
    while (start > -1) {
      if (start > 0 && src[start - 1] == '\\') {
        // this open token is escaped. remove the backslash and continue.
        //遇到转义的开始标记,直接将前面的字符串以及开始标记追加
        builder.append(src, offset, start - offset - 1).append(openToken);
        offset = start + openToken.length();
      } else {
        // found open token. let's search close token.
        //查找到开始标记,且未转义
        if (expression == null) {
          expression = new StringBuilder();
        } else {
          expression.setLength(0);
        }
        //前面字符追加
        builder.append(src, offset, start - offset);
        offset = start + openToken.length();
        //从offset后继续查找结束标记
        int end = text.indexOf(closeToken, offset);
        while (end > -1) {
          if (end > offset && src[end - 1] == '\\') {
            // this close token is escaped. remove the backslash and continue.
            //处理转义的结束标记
            expression.append(src, offset, end - offset - 1).append(closeToken);
            offset = end + closeToken.length();
            end = text.indexOf(closeToken, offset);
          } else {
            //将开始标记和结束标记之间字符添加
            expression.append(src, offset, end - offset);
            break;
          }
        }
        if (end == -1) {
          //未找到结束标记
          // close token was not found.
          builder.append(src, start, src.length - start);
          offset = src.length;
        } else {
          //将占位符的值交给handler处理,并保存builder
          builder.append(handler.handleToken(expression.toString()));
          offset = end + closeToken.length();
        }
      }
      //移动start
      start = text.indexOf(openToken, offset);
    }
    if (offset < src.length) {
      builder.append(src, offset, src.length - offset);
    }
    return builder.toString();
  }
}
  private static class VariableTokenHandler implements TokenHandler {
    //Properties标签定义值,用于替换占位符
    private final Properties variables;
    //是否支持占位符中使用默认的功能
    private final boolean enableDefaultValue;
    //指定占位符和默认值之间的分隔符
    private final String defaultValueSeparator;
    
  @Override
    public String handleToken(String content) {
      //variables非空
      if (variables != null) {
        String key = content;
        //是否支持占位符中使用默认值功能
        if (enableDefaultValue) {
          //查找分割符
          final int separatorIndex = content.indexOf(defaultValueSeparator);
          String defaultValue = null;
          if (separatorIndex >= 0) {
            //获取占位符名称
            key = content.substring(0, separatorIndex);
            //获取默认值
            defaultValue = content.substring(separatorIndex + defaultValueSeparator.length());
          }
          if (defaultValue != null) {
            //查找指定占位符
            return variables.getProperty(key, defaultValue);
          }
        }
        //不支持默认值,则直接找
        if (variables.containsKey(key)) {
          return variables.getProperty(key);
        }
      }
      //variables空
      return "${" + content + "}";
    }
}

解析XNode

  public List<XNode> evalNodes(Object root, String expression) {
    //XNode,mybatis实现,封装node
    List<XNode> xnodes = new ArrayList<>();
    NodeList nodes = (NodeList) evaluate(expression, root, XPathConstants.NODESET);
    for (int i = 0; i < nodes.getLength(); i++) {
      xnodes.add(new XNode(this, nodes.item(i), variables));
    }
    return xnodes;
  }
public class XNode {

  //w3c对象
  private final Node node;
  //节点名
  private final String name;
  //节点内容
  private final String body;
  //节点属性集合
  private final Properties attributes;
  //Properties对应配置文件
  private final Properties variables;
  private final XPathParser xpathParser;

  public XNode(XPathParser xpathParser, Node node, Properties variables) {
    this.xpathParser = xpathParser;
    this.node = node;
    this.name = node.getNodeName();
    this.variables = variables;
    this.attributes = parseAttributes(node);
    this.body = parseBody(node);
  }

  private Properties parseAttributes(Node n) {
    Properties attributes = new Properties();
    //获取节点的属性集合
    NamedNodeMap attributeNodes = n.getAttributes();
    if (attributeNodes != null) {
      for (int i = 0; i < attributeNodes.getLength(); i++) {
        Node attribute = attributeNodes.item(i);
        //使用PropertyParser 处理每个属性中的占位符
        String value = PropertyParser.parse(attribute.getNodeValue(), variables);
        attributes.put(attribute.getNodeName(), value);
      }
    }
    return attributes;
  }


  private String parseBody(Node node) {
    String data = getBodyData(node);
    //当前节点不是文本节点
    if (data == null) {
      NodeList children = node.getChildNodes();
      for (int i = 0; i < children.getLength(); i++) {
        Node child = children.item(i);
        data = getBodyData(child);
        if (data != null) {
          break;
        }
      }
    }
    return data;
  }

  private String getBodyData(Node child) {
    //只处理文本内容
    if (child.getNodeType() == Node.CDATA_SECTION_NODE
        || child.getNodeType() == Node.TEXT_NODE) {
      String data = ((CharacterData) child).getData();
      //使用PropertyParser 处理文本节点中的占位符
      data = PropertyParser.parse(data, variables);
      return data;
    }
    return null;
  }
}

对反射支持

public class Reflector {
  //对应的Class 类型
  private final Class<?> type;
  //可读属性的名称集合,可读属性就是存在相应getter 方法的属性,初始值为空数纽
  private final String[] readablePropertyNames;
  //可写属性的名称集合,可写属性就是存在相应setter 方法的属性,初始值为空数纽
  private final String[] writablePropertyNames;
  //记录了属性相应的setter 方法, key 是属性名称, value 是Invoker 对象
  private final Map<String, Invoker> setMethods = new HashMap<>();
  //属性相应的getter 方法集合, key 是属性名称, value 也是Inv o ker 对象
  private final Map<String, Invoker> getMethods = new HashMap<>();
  //记录了属性相应的setter 方法的参数值类型, ke y 是属性名称, value 是setter 方法的参数类型
  private final Map<String, Class<?>> setTypes = new HashMap<>();
  //记录了属性相应的getter 方法的返回位类型, key 是属性名称, value 是getter 方法的返回位类型
  private final Map<String, Class<?>> getTypes = new HashMap<>();
  //记录了默认构造方法
  private Constructor<?> defaultConstructor;
  //记录了所有属性名称的集合
  private Map<String, String> caseInsensitivePropertyMap = new HashMap<>();

  public Reflector(Class<?> clazz) {
    type = clazz;
    //查找clazz 的默认构造方法(无参构造方法)
    addDefaultConstructor(clazz);
    //处理clazz 中的getter 方法,填充getMethods 集合和getTypes 集合
    addGetMethods(clazz);
    //处理clazz 中的set ter 方法,填充setMethods 集合和set Types 集合
    addSetMethods(clazz);
    //处理没有g etter I setter 方法的字段
    addFields(clazz);
    //根据getMethodslsetMethods 集合,初始化可读/写属性的名称集合
    readablePropertyNames = getMethods.keySet().toArray(new String[0]);
    writablePropertyNames = setMethods.keySet().toArray(new String[0]);
    //初始化caseinsensitivePropertyMap 集合,其中记录了所有大写格式的属性名称
    for (String propName : readablePropertyNames) {
      caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
    }
    for (String propName : writablePropertyNames) {
      caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
    }
  }
  /**
   * 填充getMethods 集合和getTypes 集合
   * @param clazz
   */
   private void addGetMethods(Class<?> clazz) {
    Map<String, List<Method>> conflictingGetters = new HashMap<>();
    //获取指定类以及其父类和接口中定义的方法
    Method[] methods = getClassMethods(clazz);
    //对get方法过滤
    Arrays.stream(methods).filter(m ->
        //JavaBean 中getter 方法的方法名长度大于3 且必须以” get ” 开头
      m.getParameterTypes().length == 0 && PropertyNamer.isGetter(m.getName()))
      .forEach(m ->
          //记录到conflictingGetters集合中
        addMethodConflict(conflictingGetters,
          //获取对应的属性名称
          PropertyNamer.methodToProperty(m.getName()), m));
    //对方法同名返回值不一样的处理
    resolveGetterConflicts(conflictingGetters);
  }

 private Method[] getClassMethods(Class<?> clazz) {
    //用于记录指定类中定义的全部方法的唯一签名以及对应的Meth od 对象
    Map<String, Method> uniqueMethods = new HashMap<>();
    Class<?> currentClass = clazz;
    while (currentClass != null && currentClass != Object.class) {
      //记录currentClass 这个类中定义的全部方法.桥方法除外
      addUniqueMethods(uniqueMethods, currentClass.getDeclaredMethods());

      // we also need to look for interface methods -
      // because the class may be abstract
      //记录接口中定义的方法
      Class<?>[] interfaces = currentClass.getInterfaces();
      for (Class<?> anInterface : interfaces) {
        addUniqueMethods(uniqueMethods, anInterface.getMethods());
      }
      //获取父类,继续while 循环
      currentClass = currentClass.getSuperclass();
    }

    Collection<Method> methods = uniqueMethods.values();

    return methods.toArray(new Method[0]);
  }


  private void addUniqueMethods(Map<String, Method> uniqueMethods, Method[] methods) {
    for (Method currentMethod : methods) {
      //过滤桥接方法,也就是为了兼容泛型,重新定义了一个方法,调用原来的方法,定位桥
      if (!currentMethod.isBridge()) {
      //方法得到的方法签名是全局唯一的,可以作为该方法 的唯一标识
        String signature = getSignature(currentMethod);
        // check to see if the method is already known
        // if it is known, then an extended class must have
        // overridden a method
        //检测是否在子类中已经添加过该方法,如果在子类中已经添加过,无须再向uniqueMethods 集合中添加该方法了
        if (!uniqueMethods.containsKey(signature)) {
        //记录该签名和方法的对应关系
          uniqueMethods.put(signature, currentMethod);
        }
      }
    }
  }
}

 private void resolveGetterConflicts(Map<String, List<Method>> conflictingGetters) {
    for (Entry<String, List<Method>> entry : conflictingGetters.entrySet()) {
      Method winner = null;
      String propName = entry.getKey();
      boolean isAmbiguous = false;
      for (Method candidate : entry.getValue()) {
        if (winner == null) {
          winner = candidate;
          continue;
        }
        //同一属性名称存在多个getter方法,则需要比较这些getter方法的返回,选择getter方法
        //迭代过程中的临时变量,用于记录迭代到目前为止,最适合作为getter 方法的Method
        Class<?> winnerType = winner.getReturnType();
        Class<?> candidateType = candidate.getReturnType();
        if (candidateType.equals(winnerType)) {
          //对boolean处理
          if (!boolean.class.equals(candidateType)) {
            isAmbiguous = true;
            break;
          } else if (candidate.getName().startsWith("is")) {
            winner = candidate;
          }
        } else if (candidateType.isAssignableFrom(winnerType)) {
          // OK getter type is descendant
          //当前最适合的方法的返回佳是当前方法返回的子类,什么都不做,当前最适合的方法 依然不变
        } else if (winnerType.isAssignableFrom(candidateType)) {
          //当前方法的返回位是当前最适合的方法的返回值的子类,更新临时交量getter,当前的getter 方法成为最适合的getter 方法
          winner = candidate;
        } else {
          //返回值相同,二义性,抛出异常
          isAmbiguous = true;
          break;
        }
      }
      //添加到getMethods 集合并填充get Types 集合
      addGetMethod(propName, winner, isAmbiguous);
    }
  }



 /**
   * 添加字段
   * @param clazz
   */
  private void addFields(Class<?> clazz) {
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
      //当setMethods 集合不包含同名属性时,将其记录到setMethods 集合和set Types 集合
      if (!setMethods.containsKey(field.getName())) {
        // issue #379 - removed the check for final because JDK 1.5 allows
        // modification of final fields through reflection (JSR-133). (JGB)
        // pr #16 - final static can only be set by the classloader
        int modifiers = field.getModifiers();
        //过滤掉final和static 修饰的字段
        if (!(Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers))) {
          addSetField(field);
        }
      }
      //当getMethods 集合中不包含同名属性时,将其记录到getMethods 集合和getTypes 集合
      if (!getMethods.containsKey(field.getName())) {
        addGetField(field);
      }
    }
    if (clazz.getSuperclass() != null) {
      //处理父类中定义的字段
      addFields(clazz.getSuperclass());
    }
  }
}

添加方法的时候,会转成invoke类型
在这里插入图片描述
在这里插入图片描述
四个实现类,分别对应方法,字段
在这里插入图片描述

  @Override
  public Object invoke(Object target, Object[] args) throws IllegalAccessException {
    try {
      //返回字段值
      return field.get(target);
    } catch (IllegalAccessException e) {
      if (Reflector.canControlMemberAccessible()) {
        field.setAccessible(true);
        return field.get(target);
      } else {
        throw e;
      }
    }
  }

ReflectorFactory

/**
 * 对Reflector 对象的创建和缓存
 */
public interface ReflectorFactory {

  //检测该ReflectorFactory对象是否会缓存Reflector对象
  boolean isClassCacheEnabled();

  //设置是否缓存Reflector 对象
  void setClassCacheEnabled(boolean classCacheEnabled);

  //创建指定Class 对应的Reflector 对象
  Reflector findForClass(Class<?> type);
}

public class DefaultReflectorFactory implements ReflectorFactory {
  //该字段决定是否开启对Reflector 对象的缓存
  private boolean classCacheEnabled = true;
  //使用ConcurrentMap 集合实现对Reflector 对象的缓存
  private final ConcurrentMap<Class<?>, Reflector> reflectorMap = new ConcurrentHashMap<>();

  @Override
  public Reflector findForClass(Class<?> type) {
    //检测是否开启缓存
    if (classCacheEnabled) {
      // synchronized (type) removed see issue #461
      return reflectorMap.computeIfAbsent(type, Reflector::new);
    } else {
      //未开启缓存,则直接创建并返回Reflector对象
      return new Reflector(type);
    }
  }

}

ObjectFactory


public interface ObjectFactory {

  //设置配置信息
  default void setProperties(Properties properties) {
    // NOP
  }


  //通过无参构造器创建指定类的对象
  <T> T create(Class<T> type);


  //根据参数列表,从指定类型中选择合适的构造器创建对象
  <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);


  //检测指定类型是否为集合类型,主妥处理java.util.Collection 及其子类
  <T> boolean isCollection(Class<T> type);

}


public class DefaultObjectFactory implements ObjectFactory, Serializable {

  private static final long serialVersionUID = -8855120656740914948L;
  public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    Class<?> classToCreate = resolveInterface(type);
    // we know types are assignable
    return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
  }

private  <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    try {
      Constructor<T> constructor;
      //通过无参构造函数创建对象
      if (constructorArgTypes == null || constructorArgs == null) {
        constructor = type.getDeclaredConstructor();
        try {
          return constructor.newInstance();
        } catch (IllegalAccessException e) {
          if (Reflector.canControlMemberAccessible()) {
            constructor.setAccessible(true);
            return constructor.newInstance();
          } else {
            throw e;
          }
        }
      }
      //根据指定的参数列表查找构造函数,并实例化对象
      constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[0]));
      try {
        return constructor.newInstance(constructorArgs.toArray(new Object[0]));
      } catch (IllegalAccessException e) {
        if (Reflector.canControlMemberAccessible()) {
          constructor.setAccessible(true);
          return constructor.newInstance(constructorArgs.toArray(new Object[0]));
        } else {
          throw e;
        }
      }
    } catch (Exception e) {
      String argTypes = Optional.ofNullable(constructorArgTypes).orElseGet(Collections::emptyList)
          .stream().map(Class::getSimpleName).collect(Collectors.joining(","));
      String argValues = Optional.ofNullable(constructorArgs).orElseGet(Collections::emptyList)
          .stream().map(String::valueOf).collect(Collectors.joining(","));
      throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e);
    }
  }
}

Property

/*
解析这样的格式orders[O].items[1].name
继承了迭代器,所以可以重复解析

<resultMap id= ” rrn4testProTool ” type= ” User” >
<id column = ” id” property= ” id” />
<result property= ” orders[0].i terns[ 0]. name” column= ” iternl ” />
<result property= ” orders [O].items [1]. name ” column= ” item2 ” />
</ resultMap>
 */
public class PropertyTokenizer implements Iterator<PropertyTokenizer> {
  //当前表达式的名称
  private String name;
  //当前表达式的索引名
  private final String indexedName;
  //索引下标
  private String index;
  //子表达式
  private final String children;

  public PropertyTokenizer(String fullname) {
    //查找”.”的位置
    int delim = fullname.indexOf('.');
    if (delim > -1) {
      //初始化name
      name = fullname.substring(0, delim);
      //初始化children
      children = fullname.substring(delim + 1);
    } else {
      name = fullname;
      children = null;
    }
    //初始化indexedName
    indexedName = name;
    delim = name.indexOf('[');
    if (delim > -1) {
      //初始化index
      index = name.substring(delim + 1, name.length() - 1);
      name = name.substring(0, delim);
    }
  }
  }

/**
 * 方法名转换以及检测是否get/set
 * @author Clinton Begin
 */
public final class PropertyNamer {

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

  //将方法名转换成属性名
  public static String methodToProperty(String name) {
    if (name.startsWith("is")) {
      name = name.substring(2);
    } else if (name.startsWith("get") || name.startsWith("set")) {
      name = name.substring(3);
    } else {
      throw new ReflectionException("Error parsing property name '" + name + "'.  Didn't start with 'is', 'get' or 'set'.");
    }

    if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
      name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
    }

    return name;
  }

  //检测方法名是否对应属性名
  public static boolean isProperty(String name) {
    return isGetter(name) || isSetter(name);
  }

  //检测方法是否为getter方法
  public static boolean isGetter(String name) {
    return (name.startsWith("get") && name.length() > 3) || (name.startsWith("is") && name.length() > 2);
  }

  //检测方法是否为setter方法
  public static boolean isSetter(String name) {
    return name.startsWith("set") && name.length() > 3;
  }

}

public final class PropertyCopier {

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

  public static void copyBeanProperties(Class<?> type, Object sourceBean, Object destinationBean) {
    Class<?> parent = type;
    while (parent != null) {
      final Field[] fields = parent.getDeclaredFields();
      for (Field field : fields) {
        try {
          try {
            field.set(destinationBean, field.get(sourceBean));
          } catch (IllegalAccessException e) {
            if (Reflector.canControlMemberAccessible()) {
              field.setAccessible(true);
              //将sourceBean对象中的属性值设置到destinationBean对象中
              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.getSuperclass();
    }
  }

}

MetaClass

/**
 * 通过Reflector 和PropertyTokenizer组合使用
 * 对复杂的属性表达式的解析
 * 并实现了获取指定属性描述信息的功能。
 * @author Clinton Begin
 */
public class MetaClass {

  private final ReflectorFactory reflectorFactory;
  //在创建MetaClass 时会指定一个类,该Reflector 对象会用于记录该类相关的元信息
  private final Reflector reflector;

  private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) {
    this.reflectorFactory = reflectorFactory;
    this.reflector = reflectorFactory.findForClass(type);
  }
  
  public String findProperty(String name) {
    StringBuilder prop = buildProperty(name, new StringBuilder());
    return prop.length() > 0 ? prop.toString() : null;
  }

private StringBuilder buildProperty(String name, StringBuilder builder) {
    //解析属性表达式
    PropertyTokenizer prop = new PropertyTokenizer(name);
    //是否还有子表达式
    if (prop.hasNext()) {
      //查找PropertyTokenizer.name对应的属性
      String propertyName = reflector.findPropertyName(prop.getName());
      if (propertyName != null) {
        //追加属性名
        builder.append(propertyName);
        builder.append(".");
        //为该属性创建对应的MetaClass 对象
        MetaClass metaProp = metaClassForProperty(propertyName);
        //递归解析PropertyTokenizer.children字段,并将解析结果添加到builder中保存
        metaProp.buildProperty(prop.getChildren(), builder);
      }
    } else {
      //递归出口
      String propertyName = reflector.findPropertyName(name);
      if (propertyName != null) {
        builder.append(propertyName);
      }
    }
    return builder;
  }	

  public boolean hasGetter(String name) {
    PropertyTokenizer prop = new PropertyTokenizer(name);
    if (prop.hasNext()) {
      //PropertyTokenizer.narne 指定的属性有getter 方法,才能处理子表达式
      if (reflector.hasGetter(prop.getName())) {
        MetaClass metaProp = metaClassForProperty(prop);
        return metaProp.hasGetter(prop.getChildren());
      } else {
        return false;
      }
    } else {
      return reflector.hasGetter(prop.getName());
    }
  }

  private MetaClass metaClassForProperty(PropertyTokenizer prop) {
    //获取表达式所表示的属性的类型
    Class<?> propType = getGetterType(prop);
    return MetaClass.forClass(propType, reflectorFactory);
  }

  private Class<?> getGetterType(PropertyTokenizer prop) {
    //获取属性类型
    Class<?> type = reflector.getGetterType(prop.getName());
    //该表达式中是否使用” [] ” 指定了下标, 且是Collection 子类
    if (prop.getIndex() != null && Collection.class.isAssignableFrom(type)) {
      //通过TypeParameterResolver 工具类解析属性的类型
      Type returnType = getGenericGetterType(prop.getName());
//针对ParameterizedType 进行处理, 针对泛型集合类型进行处理
      if (returnType instanceof ParameterizedType) {
        //获取实际的类型参数
        Type[] actualTypeArguments = ((ParameterizedType) returnType).getActualTypeArguments();
        if (actualTypeArguments != null && actualTypeArguments.length == 1) {
          //泛型的类型
          returnType = actualTypeArguments[0];
          if (returnType instanceof Class) {
            type = (Class<?>) returnType;
          } else if (returnType instanceof ParameterizedType) {
            type = (Class<?>) ((ParameterizedType) returnType).getRawType();
          }
        }
      }
    }
    return type;
  }
 private Type getGenericGetterType(String propertyName) {
    try {
      //根据Reflector . getMethods 集合中记录的Invoker 实现类的类型,决定解析getter 方法返回值
    //类型还是解析字段类型
      Invoker invoker = reflector.getGetInvoker(propertyName);
      if (invoker instanceof MethodInvoker) {
        Field declaredMethod = MethodInvoker.class.getDeclaredField("method");
        declaredMethod.setAccessible(true);
        Method method = (Method) declaredMethod.get(invoker);
        return TypeParameterResolver.resolveReturnType(method, reflector.getType());
      } else if (invoker instanceof GetFieldInvoker) {
        Field declaredField = GetFieldInvoker.class.getDeclaredField("field");
        declaredField.setAccessible(true);
        Field field = (Field) declaredField.get(invoker);
        return TypeParameterResolver.resolveFieldType(field, reflector.getType());
      }
    } catch (NoSuchFieldException | IllegalAccessException e) {
      // Ignored
    }
    return null;
  }

ObjectWrapper

/**
 * 是对对象的包装,抽象了对象的属性信息,它定义了一系列查
 * 询对象属性信息的方法,以及更新属性的方法。
 * @author Clinton Begin
 */
public interface ObjectWrapper {
  // 如采Object Wrapper 中封装的是普通的Bean 对象,则调用相应属性的相应getter 方法,
  // 如采封装的是集合类,则获取指定key 或下标对应的value 位
  Object get(PropertyTokenizer prop);

  void set(PropertyTokenizer prop, Object value);

  // 查找属性表达式指定的属性,第二个参数表示是否忽略属性表达式中的下画线
  String findProperty(String name, boolean useCamelCaseMapping);

  // 查找可读属性的名称集合
  String[] getGetterNames();

  //查找可写属性的名称集合
  String[] getSetterNames();

  //解析属性表达式指定属性的setter 方法的参数类型
  Class<?> getSetterType(String name);

  //解析属性表达式指定属性的getter 方法的返回值类型
  Class<?> getGetterType(String name);

  boolean hasSetter(String name);

  boolean hasGetter(String name);

  // 为属性表达式指定的属性创建相应的MetaObject 对象
  MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory);

  // 封装的对象是否为C o lle ction 类型
  boolean isCollection();

  // 调用Collection 对象的add ()方法
  void add(Object element);

  // 调用Co lle ction 对象的addAll ()方法
  <E> void addAll(List<E> element);

}

public class BeanWrapper extends BaseWrapper {
  @Override
  public Object get(PropertyTokenizer prop) {
    //存在索引信息,则表示属性表达式中的name 部分为集合类型
    if (prop.getIndex() != null) {
      // 通过MetaObject.getValue()方法获取object对象中的指定集合属性
      Object collection = resolveCollection(prop, object);
      return getCollectionValue(prop, collection);
    } else {
      //不存在索引信息,则name 部分为普通对象,查找并调用Invoker 相关方法获取属性
      return getBeanProperty(prop, object);
    }
  } 

 protected Object getCollectionValue(PropertyTokenizer prop, Object collection) {
  //如果是Map类型,则index为key
    if (collection instanceof Map) {
      return ((Map) collection).get(prop.getIndex());
    } else {
      //如采是其他集合类型,则index 为下标
      int i = Integer.parseInt(prop.getIndex());
      if (collection instanceof List) {
        return ((List) collection).get(i);
      } else if (collection instanceof Object[]) {
        return ((Object[]) collection)[i];
      } else if (collection instanceof char[]) {
        return ((char[]) collection)[i];
      } else if (collection instanceof boolean[]) {
        return ((boolean[]) collection)[i];
      } else if (collection instanceof byte[]) {
        return ((byte[]) collection)[i];
      } else if (collection instanceof double[]) {
        return ((double[]) collection)[i];
      } else if (collection instanceof float[]) {
        return ((float[]) collection)[i];
      } else if (collection instanceof int[]) {
        return ((int[]) collection)[i];
      } else if (collection instanceof long[]) {
        return ((long[]) collection)[i];
      } else if (collection instanceof short[]) {
        return ((short[]) collection)[i];
      } else {
        throw new ReflectionException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
      }
    }
  }

 }
  
  

MetaObject

/**
 * 解析属性表达式
 * @author Clinton Begin
 */
public class MetaObject {
//原始JavaBean对象
  private final Object originalObject;
//其中封装了originalObject,以及MetaObject对象
  private final ObjectWrapper objectWrapper;
  //负责实例化originalObject 的工厂对象
  private final ObjectFactory objectFactory;
  //负责创建ObjectWrapper 的工厂对象
  private final ObjectWrapperFactory objectWrapperFactory;
 // 用于创建并缓存Reflector 对象的工厂对象
  private final ReflectorFactory reflectorFactory;

  private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
    this.originalObject = object;
    this.objectFactory = objectFactory;
    this.objectWrapperFactory = objectWrapperFactory;
    this.reflectorFactory = reflectorFactory;

    if (object instanceof ObjectWrapper) {
      this.objectWrapper = (ObjectWrapper) object;
    } else if (objectWrapperFactory.hasWrapperFor(object)) {
     //若ObjectWrapperFactory 能够为该原始对象创建对应的ObjectWrapper 对象,则由优先使用ObjectWrapperFactory
//而DefaultObjectWrapperFactory.hasWrapperFor ()始终
//返回false 。用户可以自定义ObjectWrapperFactory 实现进行扩展
      this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
    } else if (object instanceof Map) {
      this.objectWrapper = new MapWrapper(this, (Map) object);
    } else if (object instanceof Collection) {
      this.objectWrapper = new CollectionWrapper(this, (Collection) object);
    } else {
      this.objectWrapper = new BeanWrapper(this, object);
    }
  }

  public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
    if (object == null) {
    //  若object 为null ,则统一返回SystemMetaObject.NULL_META_OBJECT 这个标志对象
      return SystemMetaObject.NULL_META_OBJECT;
    } else {
      return new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
    }
  }



}

类型转换

TypeHandler

/**
 * java类型 <=>SQL数据类型
 * @author Clinton Begin
 */
public interface TypeHandler<T> {
  //在通过PreparedStatement 为SQL 语句绑定参数时,会将数据由JdbcType 类型转换成Java 类型
  void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

  /**
   * Gets the result.
   *
   * @param rs
   *          the rs
   * @param columnName
   *          Colunm name, when configuration <code>useColumnLabel</code> is <code>false</code>
   * @return the result
   * @throws SQLException
   *           the SQL exception
   */
 //从ResultSet 中获取数据时会调用此方法,会将数据由Java 类型转换成JdbcType 类型
  T getResult(ResultSet rs, String columnName) throws SQLException;

  T getResult(ResultSet rs, int columnIndex) throws SQLException;

  T getResult(CallableStatement cs, int columnIndex) throws SQLException;

}


TypeHandlerRegistry

/**
 * 管理TypeHandler
 * @author Clinton Begin
 * @author Kazuki Shimizu
 */
public final class TypeHandlerRegistry {
// 记录JdbcType 与TypeHandler 之间的对应关系,其中JdbcType 是一个枚举类型,它定义对应的J DBC 类型
//该集合主要用于从结果集读取数据时,将数据从Jdbc 类型转换成Java 类型
  private final Map<JdbcType, TypeHandler<?>>  jdbcTypeHandlerMap = new EnumMap<>(JdbcType.class);
// 记录了Java 类型向指定JdbcType 转换时,需妥使用的TypeHandler 对象。例如: Java 类型中的String 可能
//转换成数据库的char 、varchar 等多种类型,所以存在一对多关系
  private final Map<Type, Map<JdbcType, TypeHandler<?>>> typeHandlerMap = new ConcurrentHashMap<>();
  private final TypeHandler<Object> unknownTypeHandler;
// 记录了全部TypeHandler 的类型以及该类型相应的T ypeHandler 对象
  private final Map<Class<?>, TypeHandler<?>> allTypeHandlersMap = new HashMap<>();
//空TypeHandler 集合的标识
  private static final Map<JdbcType, TypeHandler<?>> NULL_TYPE_HANDLER_MAP = Collections.emptyMap();


 // register ()方法的重载1的实现如下:
  public void register(Class<?> typeHandlerClass) {
    boolean mappedTypeFound = false;
    //获取@MappedTypes主解
    //@MappedTypes 注解用于指明该TypeHandler实现类能够处理的Java 类型的集合
    MappedTypes mappedTypes = typeHandlerClass.getAnnotation(MappedTypes.class);
    if (mappedTypes != null) {
      //根据@ MappedTypes i主解中指定的Java 类型进行注册
      for (Class<?> javaTypeClass : mappedTypes.value()) {
        register(javaTypeClass, typeHandlerClass);
        mappedTypeFound = true;
      }
    }
    if (!mappedTypeFound) {
      //未指定@ MappedTypes 注解,交由重载2继续处理
      register(getInstance(null, typeHandlerClass));
    }
  }

//register ()方法的重载2的实现如下:
  public <T> void register(TypeHandler<T> typeHandler) {
    boolean mappedTypeFound = false;
    //获取@ MappedTypes 注解,并根据自MappedTypes 注解指定的Java 类型进行注册,逻辑与重载1类似
    MappedTypes mappedTypes = typeHandler.getClass().getAnnotation(MappedTypes.class);
    if (mappedTypes != null) {
      for (Class<?> handledType : mappedTypes.value()) {
        //交由重载3处理
        register(handledType, typeHandler);
        mappedTypeFound = true;
      }
    }
    // @since 3.1.0 - try to auto-discover the mapped type
    //从3 . 1. 0 版本开始,可以根据Type Handler 类型自动查找对应的Java 类型,这需妥
//我们的TypeHandler 实现类同时继承Type Reference 这个抽象类
    if (!mappedTypeFound && typeHandler instanceof TypeReference) {
      try {
        TypeReference<T> typeReference = (TypeReference<T>) typeHandler;
        //交由重载3处理
        register(typeReference.getRawType(), typeHandler);
        mappedTypeFound = true;
      } catch (Throwable t) {
        // maybe users define the TypeReference with a different type and are not assignable, so just ignore it
      }
    }
    if (!mappedTypeFound) {
      register((Class<T>) null, typeHandler);
    }
  }

 // register ()方法的重载3的实现如下:
  private <T> void register(Type javaType, TypeHandler<? extends T> typeHandler) {
    //获取@ MappedJdbcTypes j主解
    //指明该TypeHandler 实现类能够处理的JDBC 类型集合。
    MappedJdbcTypes mappedJdbcTypes = typeHandler.getClass().getAnnotation(MappedJdbcTypes.class);
    if (mappedJdbcTypes != null) {
      for (JdbcType handledJdbcType : mappedJdbcTypes.value()) {
        // 交由重载4完成注册
        register(javaType, handledJdbcType, typeHandler);
      }
      if (mappedJdbcTypes.includeNullJdbcType()) {
        // 交由重载4完成注册
        register(javaType, null, typeHandler);
      }
    } else {
      // 交由重载4完成注册
      register(javaType, null, typeHandler);
    }
  }


//register ()方法的重载4的实现如下:
  private void register(Type javaType, JdbcType jdbcType, TypeHandler<?> handler) {
    //检测是否明确指定了TypeHandler 能够处理的Java 类型
    if (javaType != null) {
      //获取指定Java 类型在TYPE HANDLER MAP 集合中对应的TypeHandler 集合
      Map<JdbcType, TypeHandler<?>> map = typeHandlerMap.get(javaType);

     // 创建新的TypeHandler 集合,并添加到typeHandlerMap中
      if (map == null || map == NULL_TYPE_HANDLER_MAP) {
        map = new HashMap<>();
      }
      //将TypeHandler 对象注册到typeHandlerMap集合
      map.put(jdbcType, handler);
      typeHandlerMap.put(javaType, map);
    }
    //向allTypeHandlersMap集合注册TypeHandler 类型和对应的TypeHandler 对象
    allTypeHandlersMap.put(handler.getClass(), handler);
  }

  //register ()方法的重载5的实现如下:
  public void register(JdbcType jdbcType, TypeHandler<?> handler) {
   //注册JDBC 类型对应的Type Handler
    jdbcTypeHandlerMap.put(jdbcType, handler);
  }

//下面是register ()方法的重载⑥的实现, 主要用来自动扫描指定包下的TypeHandler实现类并完成注册
  public void register(String packageName) {
    ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<>();
    //查找指定包下的Type Handler 接口实现类
    resolverUtil.find(new ResolverUtil.IsA(TypeHandler.class), packageName);
    Set<Class<? extends Class<?>>> handlerSet = resolverUtil.getClasses();
    for (Class<?> type : handlerSet) {
      //Ignore inner classes and interfaces (including package-info.java) and abstract classes
      //过滤掉内部类、接口以及抽象类
      if (!type.isAnonymousClass() && !type.isInterface() && !Modifier.isAbstract(type.getModifiers())) {
        //交由重载1继续后续注册操作
        register(type);
      }
    }
  }

 /**
   * 根据指定的Java类型和JdbcType 类型查找相应的TypeHandler对象,
   * @param type
   * @return
   */
  private <T> TypeHandler<T> getTypeHandler(Type type, JdbcType jdbcType) {
    if (ParamMap.class.equals(type)) {
      return null;
    }
    //查找(或初始化) Java 类型对应的TypeHandler集合
    Map<JdbcType, TypeHandler<?>> jdbcHandlerMap = getJdbcHandlerMap(type);
    TypeHandler<?> handler = null;
    if (jdbcHandlerMap != null) {
      // 根据JdbcType 类型查找TypeHandler 对象
      handler = jdbcHandlerMap.get(jdbcType);
      if (handler == null) {
        handler = jdbcHandlerMap.get(null);
      }
      if (handler == null) {
        // #591
        //如果jdbcHandlerMap 只注册了一个Type Handler ,则使用此TypeHandler 对象
        handler = pickSoleHandler(jdbcHandlerMap);
      }
    }
    // type drives generics here
    return (TypeHandler<T>) handler;
  }

 private Map<JdbcType, TypeHandler<?>> getJdbcHandlerMap(Type type) {
    //查找指定Java 类型对应的TypeHandler 集合
    Map<JdbcType, TypeHandler<?>> jdbcHandlerMap = typeHandlerMap.get(type);
    //检测是否为空集合标识
    if (NULL_TYPE_HANDLER_MAP.equals(jdbcHandlerMap)) {
      return null;
    }
    //初始化指定Java 类型的T ypeHandler 集合
    if (jdbcHandlerMap == null && type instanceof Class) {
      Class<?> clazz = (Class<?>) type;
      //枚举类型的处理
      if (Enum.class.isAssignableFrom(clazz)) {
        Class<?> enumClass = clazz.isAnonymousClass() ? clazz.getSuperclass() : clazz;
        jdbcHandlerMap = getJdbcHandlerMapForEnumInterfaces(enumClass, enumClass);
        if (jdbcHandlerMap == null) {
          register(enumClass, getInstance(enumClass, defaultEnumTypeHandler));
          return typeHandlerMap.get(enumClass);
        }
      } else {
        //查找父类对应的TypeHandler 集合,并作为初始集合
        jdbcHandlerMap = getJdbcHandlerMapForSuperclass(clazz);
      }
    }
    typeHandlerMap.put(type, jdbcHandlerMap == null ? NULL_TYPE_HANDLER_MAP : jdbcHandlerMap);
    return jdbcHandlerMap;
  }
}



TypeAliasRegistry

 /**
   * 扫描指定包下所有的类并为指定类的子类添加别名:
   * 读取@Alias注解
   * @param packageName
   * @param superType
   */
  public void registerAliases(String packageName, Class<?> superType) {
    ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<>();
    resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
    Set<Class<? extends Class<?>>> typeSet = resolverUtil.getClasses();
    for (Class<?> type : typeSet) {
      // Ignore inner classes and interfaces (including package-info.java)
      // Skip also inner classes. See issue #6
      if (!type.isAnonymousClass() && !type.isInterface() && !type.isMemberClass()) {
        registerAlias(type);
      }
    }
  }


  public void registerAlias(String alias, Class<?> value) {
    if (alias == null) {
      throw new TypeException("The parameter alias cannot be null");
    }
    // issue #748
    //将别名转换为小写
    String key = alias.toLowerCase(Locale.ENGLISH);
    //检测别名是否已经存在
    if (typeAliases.containsKey(key) && typeAliases.get(key) != null && !typeAliases.get(key).equals(value)) {
      throw new TypeException("The alias '" + alias + "' is already mapped to the value '" + typeAliases.get(key).getName() + "'.");
    }
    typeAliases.put(key, value);
  }

日志模块

public final class LogFactory {

  /**
   * Marker to be used by logging implementations that support markers.
   */
  public static final String MARKER = "MYBATIS";
// 记录当前使用的第二方日志组件所对应的适配器的构造方法
  private static Constructor<? extends Log> logConstructor;

  static {
    //下面会针对每种日志组件调用tr yimplementation ( )方法进行尝试加载,具体调用顺序是:
    //useSlf4jLogging ()一> useCommonsLogging ()一> useLog4J2Logging ()一〉
    // useLog 4JLogging()--> useJdkLogging() -> useNoLogging()
    tryImplementation(LogFactory::useSlf4jLogging);
    tryImplementation(LogFactory::useCommonsLogging);
    tryImplementation(LogFactory::useLog4J2Logging);
    tryImplementation(LogFactory::useLog4JLogging);
    tryImplementation(LogFactory::useJdkLogging);
    tryImplementation(LogFactory::useNoLogging);
  }
  public static synchronized void useJdkLogging() {
    setImplementation(org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl.class);
  }

  private static void setImplementation(Class<? extends Log> implClass) {
    try {
    //获取指定适配器的构造方法
      Constructor<? extends Log> candidate = implClass.getConstructor(String.class);
    //实例化运配葛
      Log log = candidate.newInstance(LogFactory.class.getName());
      if (log.isDebugEnabled()) {
        log.debug("Logging initialized using '" + implClass + "' adapter.");
      }
      logConstructor = candidate;
    } catch (Throwable t) {
      throw new LogException("Error setting Log implementation.  Cause: " + t, t);
    }
  }
}
public class Jdk14LoggingImpl implements Log {
//底层封笨的〕ava .util .logging .Logger 对象
  private final Logger log;
  // 初始化java .util.logging .Logger 对象
  public Jdk14LoggingImpl(String clazz) {
    log = Logger.getLogger(clazz);
  }


  @Override
  //将请求全部委托给了java.util.logg 工ng . Logger 对象的相应方法
  public void error(String s, Throwable e) {
    log.log(Level.SEVERE, s, e);
  }
}

JDBC日志

public abstract class BaseJdbcLogger {
// 记录了PreparedStateme接口中定义的常用的set*()方法
  protected static final Set<String> SET_METHODS;
// 记录了Statement 接口和PreparedStatement 接口中与执行SQL 语句相关的方法
  protected static final Set<String> EXECUTE_METHODS = new HashSet<>();

  private final Map<Object, Object> columnMap = new HashMap<>();
//记录了PreparedStatement . set *()方法设置的key 位
  private final List<Object> columnNames = new ArrayList<>();
//记录了PreparedStatement . set *()方法设置的value 值
  private final List<Object> columnValues = new ArrayList<>();
// 用于输出日志的Log 对象
  protected final Log statementLog;
 // 记录了SQL 的层数, 用于格式化输出SQL
  protected final int queryStack;
  }
public final class ConnectionLogger extends BaseJdbcLogger implements InvocationHandler {
  public static Connection newInstance(Connection conn, Log statementLog, int queryStack) {
    //使用JDK 动态代理的方式创建代理对象
    InvocationHandler handler = new ConnectionLogger(conn, statementLog, queryStack);
    ClassLoader cl = Connection.class.getClassLoader();
    return (Connection) Proxy.newProxyInstance(cl, new Class[]{Connection.class}, handler);
  }



  @Override
  public Object invoke(Object proxy, Method method, Object[] params)
      throws Throwable {
    try {
      //如调用的是从Object继承的方法,则直接调用,不做任何其他处理
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, params);
      }
      //如果调用的是prepareStatement ()方法、prepareCall ()方法或createStatement()方法,
//则在创建相应Statement 对象后,为其创建代理对象并返回该代理对象
      if ("prepareStatement".equals(method.getName()) || "prepareCall".equals(method.getName())) {
        // 日志输出
        if (isDebugEnabled()) {
          debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
        }
        PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
      //为该PreparedStatement 对象创建代理对象
        stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);
        return stmt;
      } else if ("createStatement".equals(method.getName())) {
        Statement stmt = (Statement) method.invoke(connection, params);
        stmt = StatementLogger.newInstance(stmt, statementLog, queryStack);
        return stmt;
      } else {
        return method.invoke(connection, params);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
  }

}
public final class PreparedStatementLogger extends BaseJdbcLogger implements InvocationHandler {

@Override
  public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, params);
      }
      //调用了EXECUTE_METHODS集合中的方法
      if (EXECUTE_METHODS.contains(method.getName())) {
        if (isDebugEnabled()) {
          // 日志输出,输出的是参数值以及参数类型
          debug("Parameters: " + getParameterValueString(), true);
        }
        // 清空BaseJdbcLogger 中定义的三个column *集合
        clearColumnInfo();

        if ("executeQuery".equals(method.getName())) {
          //如果调用executeQuery ()方法, 则为ResultSet 创建代理对象
          ResultSet rs = (ResultSet) method.invoke(statement, params);
          return rs == null ? null : ResultSetLogger.newInstance(rs, statementLog, queryStack);
        } else {
          return method.invoke(statement, params);
        }
      } else if (SET_METHODS.contains(method.getName())) {
        //如果调用SET_METHODS 集合中的方法, 则通过setColumn ()方法记录到BaseJdbcLogger 中定义的三个column *集合
        if ("setNull".equals(method.getName())) {
          setColumn(params[0], null);
        } else {
          setColumn(params[0], params[1]);
        }
        return method.invoke(statement, params);
      } else if ("getResultSet".equals(method.getName())) {
        //如果调用getResultSet ()方法,则为ResultSet创建代理对象
        ResultSet rs = (ResultSet) method.invoke(statement, params);
        return rs == null ? null : ResultSetLogger.newInstance(rs, statementLog, queryStack);
      } else if ("getUpdateCount".equals(method.getName())) {
        //如果调用getUpdateCount ( )方法,则通过日志框架输出其结果
        int updateCount = (Integer) method.invoke(statement, params);
        if (updateCount != -1) {
          debug("   Updates: " + updateCount, false);
        }
        return updateCount;
      } else {
        return method.invoke(statement, params);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
  }


}
public final class ResultSetLogger extends BaseJdbcLogger implements InvocationHandler {
// 记录了超大长度的类型
  private static final Set<Integer> BLOB_TYPES = new HashSet<>();
  // 是否是ResultSet 结采集的第一行
  private boolean first = true;
  // 统计行数
  private int rows;
  // 真正的ResultSet 对象
  private final ResultSet rs;
  // 记录了起大字段的列编号
  private final Set<Integer> blobColumns = new HashSet<>();


 @Override
  public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, params);
      }
      Object o = method.invoke(rs, params);
      //针对ResultSet.next ()方法的处理
      if ("next".equals(method.getName())) {
        //是否还存在下一行数据
        if ((Boolean) o) {
          rows++;
          if (isTraceEnabled()) {
            ResultSetMetaData rsmd = rs.getMetaData();
            //获取数据集的列数
            final int columnCount = rsmd.getColumnCount();
            //如采是第一行数据,则输出表头
            if (first) {
              first = false;
              //除了输出农头,还会填充blobColurnns 集合,记录超大类型的列
              printColumnHeaders(rsmd, columnCount);
            }
            //输出该H记录,注意会过滤掉blobColurnns 中记录的列,这些列的数据较大,不会输出到日志
            printColumnValues(columnCount);
          }
        } else {
          //边历完ResultSet 之后,会输出总函数
          debug("     Total: " + rows, false);
        }
      }
      // 清空BaseJdbcLogger 中的column *集合
      clearColumnInfo();
      return o;
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
  }
}

类加载器

ClassLoaderWrapper

/**
 * 会按照指定的顺序依次检测其中封装的ClassLoader 对象,并从中选取第一
 * 个可用的ClassLoader 完成相关功能。
 * A class to wrap access to multiple class loaders making them work as one
 *
 * @author Clinton Begin
 */
public class ClassLoaderWrapper {
  // 应用指定的默认类加载器
  ClassLoader defaultClassLoader;
  // System ClassLoader
  ClassLoader systemClassLoader;

  ClassLoaderWrapper() {
    try {
      //初始化systemClassLoader 字段
      systemClassLoader = ClassLoader.getSystemClassLoader();
    } catch (SecurityException ignored) {
      // AccessControlException on Google App Engine
    }
  }

  public URL getResourceAsURL(String resource, ClassLoader classLoader) {
    return getResourceAsURL(resource, getClassLoaders(classLoader));
  }

 URL getResourceAsURL(String resource, ClassLoader[] classLoader) {

    URL url;
    // 遍历ClassLoader 数纽
    for (ClassLoader cl : classLoader) {

      if (null != cl) {
//调用ClassLoader.getResource ()方法查找指定的资源
        // look for the resource as passed in...
        url = cl.getResource(resource);

        // ...but some class loaders want this leading "/", so we'll add it
        // and try again if we didn't find the resource
        if (null == url) {
         //尝试以” / ”开头,再次查找
          url = cl.getResource("/" + resource);
        }

        // "It's always in the last place I look for it!"
        // ... because only an idiot would keep looking for it after finding it, so stop looking already.
       //查找到指定的资源
        if (null != url) {
          return url;
        }

      }

    }

    // didn't find it anywhere.
    return null;

  }

  /**
   * 返回Class Loader[]数组,该数组指明了类加载器的使用顺序
   * @param classLoader
   * @return
   */
  ClassLoader[] getClassLoaders(ClassLoader classLoader) {
    return new ClassLoader[]{
      //参数指定的类加载器
      classLoader,
      //系统指定的默认类加载器
      defaultClassLoader,
      // 当前线程绑定的类加载器
      Thread.currentThread().getContextClassLoader(),
      // 加载当前类所使用的类加载器
      getClass().getClassLoader(),
      //System Cl assLoader
      systemClassLoader};
  }

}

ResolverUtil

// 根据指定的条件查找指定包下的类
public class ResolverUtil<T> {
  /**
   * A simple interface that specifies how to test classes to determine if they
   * are to be included in the results produced by the ResolverUtil.
   */
  public interface Test {

    /**
     * Will be called repeatedly with candidate classes. Must return True if a class
     * is to be included in the results, false otherwise.
     * 如果该类符合检测的条件,则matches ()方法返回true ,否则返回false
     * @param type  待检测的类
     *          the type
     * @return true, if successful
     */
    boolean matches(Class<?> type);
  }

 /**
   * A Test that checks to see if each class is assignable to the provided class. Note
   * that this test will match the parent type itself if it is presented for matching.
   * 检测类是否继承了指定的类或接口
   */
  public static class IsA implements Test {}

  /**
   * A Test that checks to see if each class is annotated with a specific annotation. If it
   * is, then the test returns true, otherwise false.
   *
   * 检测类是否添加了指定的注解
   */
  public static class AnnotatedWith implements Test {}

 public ResolverUtil<T> find(Test test, String packageName) {
    //根据包名获取其对应的路径
    String path = getPackagePath(packageName);

    try {
      //查找packageName 包下的所有资源
      List<String> children = VFS.getInstance().list(path);
      for (String child : children) {
        if (child.endsWith(".class")) {
          // 检测该类是否符合test 条件
          addIfMatching(test, child);
        }
      }
    } catch (IOException ioe) {
      log.error("Could not read package: " + packageName, ioe);
    }

    return this;
  }


  protected void addIfMatching(Test test, String fqn) {
    try {
      // fqn 是类的完全限定名,即包括其所在包的包名
      String externalName = fqn.substring(0, fqn.indexOf('.')).replace('/', '.');
      ClassLoader loader = getClassLoader();
      if (log.isDebugEnabled()) {
        log.debug("Checking to see if class " + externalName + " matches criteria [" + test + "]");
      }

      // 加载指定的类
      Class<?> type = loader.loadClass(externalName);
     //通过Test.matches ()方法检测条件是否满足
      if (test.matches(type)) {
        //将符合条件的类记录到matches 集合中
        matches.add((Class<T>) type);
      }
    } catch (Throwable t) {
      log.warn("Could not examine class '" + fqn + "'" + " due to a "
          + t.getClass().getName() + " with message: " + t.getMessage());
    }
  }

  /**
   * Returns the classloader that will be used for scanning for classes. If no explicit
   * ClassLoader has been set by the calling, the context class loader will be used.
   *
   * @return the ClassLoader that will be used to scan for classes
   * 
   * 默认获取当前线程类加载器,可通过setClassLoader提前设置类加载器
   */
  public ClassLoader getClassLoader() {
    return classloader == null ? Thread.currentThread().getContextClassLoader() : classloader;
  }
}

VFS

/**
 * Provides a very simple API for accessing resources within an application server.
 * 表示虚拟文件系统( Virtual File System ) , 它用来查找指定路径下的资源。
 * @author Ben Gunter
 */
public abstract class VFS {
//羊例模式,记录了全局唯一的VFS 对象
  private static class VFSHolder {
    static final VFS INSTANCE = createVFS();

    @SuppressWarnings("unchecked")
    static VFS createVFS() {
      // Try the user implementations first, then the built-ins
      // 优先使用用户自定义的VFS 实现, 如没有自定义VFS 实现,则使用MyBatis 提供的VFS 实现
      List<Class<? extends VFS>> impls = new ArrayList<>();
      impls.addAll(USER_IMPLEMENTATIONS);
      impls.addAll(Arrays.asList((Class<? extends VFS>[]) IMPLEMENTATIONS));

      // Try each implementation class until a valid one is found
     //遍历集合,依次实例化VFS 对象并检测VFS 对象是否有效,一旦得到有效的VFS 对象,则结束循环
      VFS vfs = null;
      for (int i = 0; vfs == null || !vfs.isValid(); i++) {
        Class<? extends VFS> impl = impls.get(i);
        try {
          vfs = impl.getDeclaredConstructor().newInstance();
          if (!vfs.isValid() && log.isDebugEnabled()) {
            log.debug("VFS implementation " + impl.getName()
                + " is not valid in this environment.");
          }
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
          log.error("Failed to instantiate " + impl, e);
          return null;
        }
      }

      if (log.isDebugEnabled()) {
        log.debug("Using VFS adapter " + vfs.getClass().getName());
      }

      return vfs;
    }
  }

  /**
   * Get the singleton {@link VFS} instance. If no {@link VFS} implementation can be found for the current environment,
   * then this method returns null.
   *
   * @return single instance of VFS
   */
  public static VFS getInstance() {
    return VFSHolder.INSTANCE;
  }

}
public class DefaultVFS extends VFS {
  @Override
  /**
   * 责检测当前VFS 对象
   * 在当前环境下是否有效,
   */
  public boolean isValid() {
    return true;
  }

 @Override
  /**
   * 查找指定的资源名称列表
   */
  public List<String> list(URL url, String path) throws IOException {
    InputStream is = null;
    try {
      List<String> resources = new ArrayList<>();

      // First, try to find the URL of a JAR file containing the requested resource. If a JAR
      // file is found, then we'll list child resources by reading the JAR.
      //如果url 指向的资源在一个Jar 包中,则获取该Jar 包对应的URL ,否则返回n ull
      URL jarUrl = findJarForResource(url);
      if (jarUrl != null) {
        is = jarUrl.openStream();
        if (log.isDebugEnabled()) {
          log.debug("Listing " + url);
        }
        //遍历Jar 中的资源,并返回以path 开头的资源列表
        resources = listResources(new JarInputStream(is), path);
      } else {
        //遍历url 指向的目录,将其下资源名称记录到c hildren 集合中
        List<String> children = new ArrayList<>();
        try {
          if (isJar(url)) {
            // Some versions of JBoss VFS might give a JAR stream even if the resource
            // referenced by the URL isn't actually a JAR
            is = url.openStream();
            try (JarInputStream jarInput = new JarInputStream(is)) {
              if (log.isDebugEnabled()) {
                log.debug("Listing " + url);
              }
              for (JarEntry entry; (entry = jarInput.getNextJarEntry()) != null; ) {
                if (log.isDebugEnabled()) {
                  log.debug("Jar entry: " + entry.getName());
                }
                children.add(entry.getName());
              }
            }
          } else {
            /*
             * Some servlet containers allow reading from directory resources like a
             * text file, listing the child resources one per line. However, there is no
             * way to differentiate between directory and file resources just by reading
             * them. To work around that, as each line is read, try to look it up via
             * the class loader as a child of the current resource. If any line fails
             * then we assume the current resource is not a directory.
             */
            is = url.openStream();
            List<String> lines = new ArrayList<>();
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
              for (String line; (line = reader.readLine()) != null;) {
                if (log.isDebugEnabled()) {
                  log.debug("Reader entry: " + line);
                }
                lines.add(line);
                if (getResources(path + "/" + line).isEmpty()) {
                  lines.clear();
                  break;
                }
              }
            }
            if (!lines.isEmpty()) {
              if (log.isDebugEnabled()) {
                log.debug("Listing " + url);
              }
              children.addAll(lines);
            }
          }
        } catch (FileNotFoundException e) {
          /*
           * For file URLs the openStream() call might fail, depending on the servlet
           * container, because directories can't be opened for reading. If that happens,
           * then list the directory directly instead.
           */
          if ("file".equals(url.getProtocol())) {
            File file = new File(url.getFile());
            if (log.isDebugEnabled()) {
              log.debug("Listing directory " + file.getAbsolutePath());
            }
            if (file.isDirectory()) {
              if (log.isDebugEnabled()) {
                log.debug("Listing " + url);
              }
              children = Arrays.asList(file.list());
            }
          } else {
            // No idea where the exception came from so rethrow it
            throw e;
          }
        }

        // The URL prefix to use when recursively listing child resources
        String prefix = url.toExternalForm();
        if (!prefix.endsWith("/")) {
          prefix = prefix + "/";
        }

        // Iterate over immediate children, adding files and recursing into directories
        //遍历children 集合,递归查找符合条件的资源名称
        for (String child : children) {
          String resourcePath = path + "/" + child;
          resources.add(resourcePath);
          URL childUrl = new URL(prefix + child);
          resources.addAll(list(childUrl, resourcePath));
        }
      }

      return resources;
    } finally {
      if (is != null) {
        try {
          is.close();
        } catch (Exception e) {
          // Ignore
        }
      }
    }
  }

  protected List<String> listResources(JarInputStream jar, String path) throws IOException {
    // Include the leading and trailing slash when matching names
   //如果path 不是以”/”开始和结束,则在其开始和结束位置添加”/”
    if (!path.startsWith("/")) {
      path = "/" + path;
    }
    if (!path.endsWith("/")) {
      path = path + "/";
    }

    // Iterate over the entries and collect those that begin with the requested path
    List<String> resources = new ArrayList<>();
   //遍历整个Jar,将以path 开头的资源记录到resources 集合中并返回
    for (JarEntry entry; (entry = jar.getNextJarEntry()) != null;) {
      if (!entry.isDirectory()) {
        // Add leading slash if it's missing
        StringBuilder name = new StringBuilder(entry.getName());
        if (name.charAt(0) != '/') {
          name.insert(0, '/');
        }

        // Check file name
       //检测name 是否以path 开头
        if (name.indexOf(path) == 0) {
          if (log.isDebugEnabled()) {
            log.debug("Found resource: " + name);
          }
          // Trim leading slash
         //记录资源、名称
          resources.add(name.substring(1));
        }
      }
    }
    return resources;
  }
}

数据源

DataSourceFactory

/**
 * @author Clinton Begin
 */
public interface DataSourceFactory {
//设置Data Source 的相关属性,一般紧跟在初始化完成之后
  void setProperties(Properties props);
//获取DataSource 对象
  DataSource getDataSource();

}
public class UnpooledDataSourceFactory implements DataSourceFactory {

 public UnpooledDataSourceFactory() {
    this.dataSource = new UnpooledDataSource();
  }

  @Override
  public void setProperties(Properties properties) {
    Properties driverProperties = new Properties();
    //创建DataSource 相应的MetaObject
    MetaObject metaDataSource = SystemMetaObject.forObject(dataSource);
    //遍历properties 集合,该集合中设置了数据源需要的信息
    for (Object key : properties.keySet()) {
      String propertyName = (String) key;
      if (propertyName.startsWith(DRIVER_PROPERTY_PREFIX)) {
        String value = properties.getProperty(propertyName);
        //以” driver . ”开头的配置项是对DataSource 的配置,记录到driverProperties 中保存
        driverProperties.setProperty(propertyName.substring(DRIVER_PROPERTY_PREFIX_LENGTH), value);
      } else if (metaDataSource.hasSetter(propertyName)) {
        String value = (String) properties.get(propertyName);
        //根据属性类型进行类型转换, 主要是Integer 、Long 、Boolean 三种类型的转换
        Object convertedValue = convertValue(metaDataSource, propertyName, value);
        //设置DataSource 的相关属性值
        metaDataSource.setValue(propertyName, convertedValue);
      } else {
        throw new DataSourceException("Unknown DataSource property: " + propertyName);
      }
    }
   //设置DataSource.driverProperties 属性值
    if (driverProperties.size() > 0) {
      metaDataSource.setValue("driverProperties", driverProperties);
    }
  }
}

DataSource

public class UnpooledDataSource implements DataSource {

//加载Driver 类的类加载器
  private ClassLoader driverClassLoader;
  //数据库连接驱动的相关配置
  private Properties driverProperties;
//缓存所有已注册的数据库连接驱动
  private static Map<String, Driver> registeredDrivers = new ConcurrentHashMap<>();
//数据库连接的驱动名称
  private String driver;
  private String url;
  private String username;
  private String password;

  // 是否自动提交
  private Boolean autoCommit;
  // 事务隔离级别
  private Integer defaultTransactionIsolationLevel;
  private Integer defaultNetworkTimeout;

  static {
    //将己在DriverManager 中注册的JDBC Driver 复制一份到UnpooledDataSource.registeredDrivers 集合中。
    Enumeration<Driver> drivers = DriverManager.getDrivers();
    while (drivers.hasMoreElements()) {
      Driver driver = drivers.nextElement();
      registeredDrivers.put(driver.getClass().getName(), driver);
    }
  }


private Connection doGetConnection(Properties properties) throws SQLException {
    // 初始化数据库驱动
    initializeDriver();
    //创建真正的数据库连接
    Connection connection = DriverManager.getConnection(url, properties);
    //配置数据库连接的autoCommit 和隔离级别
    configureConnection(connection);
    return connection;
  }

  private synchronized void initializeDriver() throws SQLException {
    //检测驱动是否已注册
    if (!registeredDrivers.containsKey(driver)) {
      Class<?> driverType;
      try {
        if (driverClassLoader != null) {
          //注册驱动
          driverType = Class.forName(driver, true, driverClassLoader);
        } else {
          driverType = Resources.classForName(driver);
        }
        // DriverManager requires the driver to be loaded via the system ClassLoader.
        // http://www.kfu.com/~nsayer/Java/dyn-jdbc.html
        //创建Driver 对象
        Driver driverInstance = (Driver) driverType.getDeclaredConstructor().newInstance();
        //注册驱动, DriverProxy 是定义在UnpooledDataSource 中的内部类,是Driver 的静态代理类
        DriverManager.registerDriver(new DriverProxy(driverInstance));
        //将驱动添加到registeredDrivers 集合中
        registeredDrivers.put(driver, driverInstance);
      } catch (Exception e) {
        throw new SQLException("Error setting driver on UnpooledDataSource. Cause: " + e);
      }
    }
  }

  private void configureConnection(Connection conn) throws SQLException {
    if (defaultNetworkTimeout != null) {
      conn.setNetworkTimeout(Executors.newSingleThreadExecutor(), defaultNetworkTimeout);
    }
    if (autoCommit != null && autoCommit != conn.getAutoCommit()) {
      // 设置事务是否自动提交
      conn.setAutoCommit(autoCommit);
    }
    if (defaultTransactionIsolationLevel != null) {
      //设置事务隔离级别
      conn.setTransactionIsolation(defaultTransactionIsolationLevel);
    }
  }

}

PooledConnection

class PooledConnection implements InvocationHandler {

  private static final String CLOSE = "close";
  private static final Class<?>[] IFACES = new Class<?>[] { Connection.class };

  private final int hashCode;
  // 记录当前PooledConnecti对象所在的PooledDataSource 对象。该PooledConnection 是从
//该PooledDataSource 中获取的;当调用close ()方法时会将PooledConnection放回该PooledDataSource中
  private final PooledDataSource dataSource;
 // 真正的数据库连接
  private final Connection realConnection;
 // 数据库连接的代理对象
  private final Connection proxyConnection;
 // 从连接池中取出该连接的时间戳
  private long checkoutTimestamp;
 // 该连接创建的时间戳
  private long createdTimestamp;
 // 最后一次被使用的时间戳
  private long lastUsedTimestamp;
  // 由数据库URL 、用户名和密码计算出来的hash,可用于标识该连接所在的连接池
  private int connectionTypeCode;
  //检测当前PooledConnection 是否有效,主要是为了防止程序通过close ()方法将连接归还给连接池之后,依
//然通过该连接操作数据库
  private boolean valid;

 @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    String methodName = method.getName();
    //如果调用close ()方法,则将其重新放入连接池,而不是真正关闭数据库连接
    if (CLOSE.equals(methodName)) {
      dataSource.pushConnection(this);
      return null;
    }
    try {
      if (!Object.class.equals(method.getDeclaringClass())) {
        // issue #579 toString() should never fail
        // throw an SQLException instead of a Runtime
        // 通过valid 字段检测连接是否有效
        checkConnection();
      }
      // 调用真正数据库连接对象的对应方法
      return method.invoke(realConnection, args);
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }

  }
}

PoolState

public class PoolState {

  protected PooledDataSource dataSource;
// 空闲的PooledConnection 集合
  protected final List<PooledConnection> idleConnections = new ArrayList<>();
// 活跃的PooledConnection 集合
  protected final List<PooledConnection> activeConnections = new ArrayList<>();
  // 请求数据库连接的次数
  protected long requestCount = 0;
  // 获取连接的累积时间
  protected long accumulatedRequestTime = 0;
  // checkoutTime 表示应用从连接池中取出连接,到归还连接这段时长,
  // accumulatedCheckoutTime 记录了所有连接累积的checkout Time 时长
  protected long accumulatedCheckoutTime = 0;
  // 当连接长时间未归还给连接池时,会被认为该连接超时,
  // claimedOverdueConnectionCount 记录了超时的连接个数
  protected long claimedOverdueConnectionCount = 0;
  // 累积超时时间
  protected long accumulatedCheckoutTimeOfOverdueConnections = 0;
  // 累积等待时间
  protected long accumulatedWaitTime = 0;
  // 等待次数
  protected long hadToWaitCount = 0;
  // 无效的连接数
  protected long badConnectionCount = 0;
}

PooledDataSource

public class PooledDataSource implements DataSource {

  private static final Log log = LogFactory.getLog(PooledDataSource.class);
//通过PoolState 管理连接池的状态并记录统计信息
  private final PoolState state = new PoolState(this);

//记录Unpoo ledData Source 对象,用于生成真实的数据库连接对象,构造函数中会初始化该字段
  private final UnpooledDataSource dataSource;

  // OPTIONAL CONFIGURATION FIELDS
  //最大活跃连接数
  protected int poolMaximumActiveConnections = 10;
 // 最大空闲连接数
  protected int poolMaximumIdleConnections = 5;
 // 最大checkout 时长
  protected int poolMaximumCheckoutTime = 20000;
 // 在无法获取连接时,线程需要等待的时间
  protected int poolTimeToWait = 20000;
  protected int poolMaximumLocalBadConnectionTolerance = 3;
  // 在检测一个数据库连接是否可用时,会给数据库发送一个测试SQL 语句
  protected String poolPingQuery = "NO PING QUERY SET";
 // 是否允许发送测试SQL语句
  protected boolean poolPingEnabled;
  //当连接超过poolPingConnectionsNotUsedFor 毫秒未使用时,会发送一次测试SQL 语句,检测连接是否正常
  protected int poolPingConnectionsNotUsedFor;
//根据数据库的URL 、用户名和密码生成的一个hash 佳,该哈希值用于标志着当前的连接池,在构造函数中初始化
  private int expectedConnectionTypeCode;

private PooledConnection popConnection(String username, String password) throws SQLException {
    boolean countedWait = false;
    PooledConnection conn = null;
    long t = System.currentTimeMillis();
    int localBadConnectionCount = 0;

    while (conn == null) {
      //同步
      synchronized (state) {
        //检测空闲连接
        if (!state.idleConnections.isEmpty()) {
          // Pool has available connection
          //获取连接
          conn = state.idleConnections.remove(0);
          if (log.isDebugEnabled()) {
            log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");
          }
        } else {
          //当前连接池没有空闲连接
            // 活跃连接数没有到最大值,则可以创建新连接
          // Pool does not have available connection
          if (state.activeConnections.size() < poolMaximumActiveConnections) {
            // Can create new connection
            //创建新数据库连接,并封装成PooledConnection 对象
            conn = new PooledConnection(dataSource.getConnection(), this);
            if (log.isDebugEnabled()) {
              log.debug("Created connection " + conn.getRealHashCode() + ".");
            }
          } else {
            //活跃连接数已到最大值,则不能创建新连接
              //获取最先创建的活跃连接
            // Cannot create new connection
            PooledConnection oldestActiveConnection = state.activeConnections.get(0);
            long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();
            //连接是否超时
            if (longestCheckoutTime > poolMaximumCheckoutTime) {
              // Can claim overdue connection
              //对超时连接的信息进行统计
              state.claimedOverdueConnectionCount++;
              state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;
              state.accumulatedCheckoutTime += longestCheckoutTime;
              //将超时连接移出activeConnections集合
              state.activeConnections.remove(oldestActiveConnection);
              //如超时连接未提交,则自动回滚
              if (!oldestActiveConnection.getRealConnection().getAutoCommit()) {
                try {
                  oldestActiveConnection.getRealConnection().rollback();
                } catch (SQLException e) {
                  /*
                     Just log a message for debug and continue to execute the following
                     statement like nothing happened.
                     Wrap the bad connection with a new PooledConnection, this will help
                     to not interrupt current executing thread and give current thread a
                     chance to join the next competition for another valid/good database
                     connection. At the end of this loop, bad {@link @conn} will be set as null.
                   */
                  log.debug("Bad connection. Could not roll back");
                }
              }
              //创建新PooledConnection对象,但是真正的数据库连接并未创建新的
              conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this);
              conn.setCreatedTimestamp(oldestActiveConnection.getCreatedTimestamp());
              conn.setLastUsedTimestamp(oldestActiveConnection.getLastUsedTimestamp());
              //将起时PooledConnection 设置为无效
              oldestActiveConnection.invalidate();
              if (log.isDebugEnabled()) {
                log.debug("Claimed overdue connection " + conn.getRealHashCode() + ".");
              }
            } else {
             //无空闲连接、无法创建新连接且无超时连接,只能阻塞等待
              // Must wait
              try {
                if (!countedWait) {
                  //统计等待次数
                  state.hadToWaitCount++;
                  countedWait = true;
                }
                if (log.isDebugEnabled()) {
                  log.debug("Waiting as long as " + poolTimeToWait + " milliseconds for connection.");
                }
                long wt = System.currentTimeMillis();
                //阻塞等待
                state.wait(poolTimeToWait);
                //统计累积的等待时间
                state.accumulatedWaitTime += System.currentTimeMillis() - wt;
              } catch (InterruptedException e) {
                break;
              }
            }
          }
        }
        if (conn != null) {
          // ping to server and check the connection is valid or not
          //检测PooledConnect是否有效
          if (conn.isValid()) {
            if (!conn.getRealConnection().getAutoCommit()) {
              conn.getRealConnection().rollback();
            }
            //配置PooledConnection 的相关属性
            conn.setConnectionTypeCode(assembleConnectionTypeCode(dataSource.getUrl(), username, password));
            conn.setCheckoutTimestamp(System.currentTimeMillis());
            conn.setLastUsedTimestamp(System.currentTimeMillis());
            state.activeConnections.add(conn);
            // 进行相关统计
            state.requestCount++;
            state.accumulatedRequestTime += System.currentTimeMillis() - t;
          } else {
            if (log.isDebugEnabled()) {
              log.debug("A bad connection (" + conn.getRealHashCode() + ") was returned from the pool, getting another connection.");
            }
            state.badConnectionCount++;
            localBadConnectionCount++;
            conn = null;
            if (localBadConnectionCount > (poolMaximumIdleConnections + poolMaximumLocalBadConnectionTolerance)) {
              if (log.isDebugEnabled()) {
                log.debug("PooledDataSource: Could not get a good connection to the database.");
              }
              throw new SQLException("PooledDataSource: Could not get a good connection to the database.");
            }
          }
        }
      }

    }

    if (conn == null) {
      if (log.isDebugEnabled()) {
        log.debug("PooledDataSource: Unknown severe error condition.  The connection pool returned a null connection.");
      }
      throw new SQLException("PooledDataSource: Unknown severe error condition.  The connection pool returned a null connection.");
    }

    return conn;
  }


 protected void pushConnection(PooledConnection conn) throws SQLException {
//同步
    synchronized (state) {
 //移除该PooledConnection 对象
      state.activeConnections.remove(conn);
 //检测PooledConnection 对象是否有效
      if (conn.isValid()) {
       // 检测空闲连接数是否已达到上限,以及PooledConnection 是否为该连接池的连接
        if (state.idleConnections.size() < poolMaximumIdleConnections && conn.getConnectionTypeCode() == expectedConnectionTypeCode) {
         //累积checkout 时长
          state.accumulatedCheckoutTime += conn.getCheckoutTime();
         //回滚未提交的事务
          if (!conn.getRealConnection().getAutoCommit()) {
            conn.getRealConnection().rollback();
          }
         //为返还连接创建新的PooledConnection 对象
          PooledConnection newConn = new PooledConnection(conn.getRealConnection(), this);
         //添加到idleConnections 集合
          state.idleConnections.add(newConn);
          newConn.setCreatedTimestamp(conn.getCreatedTimestamp());
          newConn.setLastUsedTimestamp(conn.getLastUsedTimestamp());
         //将原PooledConnection 对象设置为无效
          conn.invalidate();
          if (log.isDebugEnabled()) {
            log.debug("Returned connection " + newConn.getRealHashCode() + " to pool.");
          }
          //唤醒阻塞等待的线程
          state.notifyAll();
        } else {
         //空闲连接数已达到上限或PooledConnection 对象并不属于该连接池
           // 累积checkout 时长
          state.accumulatedCheckoutTime += conn.getCheckoutTime();
          //回滚未提交的事务
          if (!conn.getRealConnection().getAutoCommit()) {
            conn.getRealConnection().rollback();
          }
         //关闭真正的数据库连接
          conn.getRealConnection().close();
          if (log.isDebugEnabled()) {
            log.debug("Closed connection " + conn.getRealHashCode() + ".");
          }
          // 将PooledConnect 工on 对象设置为元效
          conn.invalidate();
        }
      } else {
        if (log.isDebugEnabled()) {
          log.debug("A bad connection (" + conn.getRealHashCode() + ") attempted to return to the pool, discarding connection.");
        }
       // 统计元效PooledConnection 对象个敛
        state.badConnectionCount++;
      }
    }
  }

  protected boolean pingConnection(PooledConnection conn) {
    // 记录ping 操作是否成功
    boolean result = true;

    try {
      // 检测真正的数据库连接是否已经关闭
      result = !conn.getRealConnection().isClosed();
    } catch (SQLException e) {
      if (log.isDebugEnabled()) {
        log.debug("Connection " + conn.getRealHashCode() + " is BAD: " + e.getMessage());
      }
      result = false;
    }
//检测poolPingEnabled 设置,是否运行执行测试SQL 语句
// 长时间(超过poolPingConnectionsNotUsedFor 指定的时长)未使用的连接,才需要ping 操作来检测数据库连接是否正常
    if (result && poolPingEnabled && poolPingConnectionsNotUsedFor >= 0
        && conn.getTimeElapsedSinceLastUse() > poolPingConnectionsNotUsedFor) {
      try {
        if (log.isDebugEnabled()) {
          log.debug("Testing connection " + conn.getRealHashCode() + " ...");
        }
        Connection realConn = conn.getRealConnection();
        try (Statement statement = realConn.createStatement()) {
          statement.executeQuery(poolPingQuery).close();
        }
        if (!realConn.getAutoCommit()) {
          realConn.rollback();
        }
        result = true;
        if (log.isDebugEnabled()) {
          log.debug("Connection " + conn.getRealHashCode() + " is GOOD!");
        }
      } catch (Exception e) {
        log.warn("Execution of ping query '" + poolPingQuery + "' failed: " + e.getMessage());
        try {
          conn.getRealConnection().close();
        } catch (Exception e2) {
          // ignore
        }
        result = false;
        if (log.isDebugEnabled()) {
          log.debug("Connection " + conn.getRealHashCode() + " is BAD: " + e.getMessage());
        }
      }
    }
    return result;
  }

/*  当修改PooledDataSource 的字段时,
  例如数据库URL 、用户名、密码、autoCornmit 配置等, 都会调用forceCloseAll()方法将所
  有数据库连接关闭, 同时也会将所有相应的PooledConnection对象都设置为无效*/
  public void forceCloseAll() {
    synchronized (state) {
      //更新当前连接池的标识
      expectedConnectionTypeCode = assembleConnectionTypeCode(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
      // 处理全部的活跃连接
      for (int i = state.activeConnections.size(); i > 0; i--) {
        try {
          //从PoolState.activeConnections集合中获取PooledConnection 对象
          PooledConnection conn = state.activeConnections.remove(i - 1);
          //将PooledConnection对象设置为无效
          conn.invalidate();
          //获取真正的数据库连接对象
          Connection realConn = conn.getRealConnection();
          // 回滚未提交的事务
          if (!realConn.getAutoCommit()) {
            realConn.rollback();
          }
          // 关闭真正的数据库连接
          realConn.close();
        } catch (Exception e) {
          // ignore
        }
      }
      for (int i = state.idleConnections.size(); i > 0; i--) {
        try {
          PooledConnection conn = state.idleConnections.remove(i - 1);
          conn.invalidate();

          Connection realConn = conn.getRealConnection();
          if (!realConn.getAutoCommit()) {
            realConn.rollback();
          }
          realConn.close();
        } catch (Exception e) {
          // ignore
        }
      }
    }
    if (log.isDebugEnabled()) {
      log.debug("PooledDataSource forcefully closed/removed all connections.");
    }
  }
}

事务

Transaction

public interface Transaction {

  /**
   * Retrieve inner database connection.
   * @return DataBase connection
   * @throws SQLException
   *           the SQL exception
   */
  // 获取对应的数据库连接对象
  Connection getConnection() throws SQLException;

  /**
   * Commit inner database connection.
   * @throws SQLException
   *           the SQL exception
   */
  // 提交事务
  void commit() throws SQLException;

  /**
   * Rollback inner database connection.
   * @throws SQLException
   *           the SQL exception
   */
  // 回滚事务
  void rollback() throws SQLException;

  /**
   * Close inner database connection.
   * @throws SQLException
   *           the SQL exception
   */
  //关闭数据库连接
  void close() throws SQLException;

  /**
   * Get transaction timeout if set.
   *
   * @return the timeout
   * @throws SQLException
   *           the SQL exception
   */
  //获取事务超时时间
  Integer getTimeout() throws SQLException;

}
public class JdbcTransaction implements Transaction {

  private static final Log log = LogFactory.getLog(JdbcTransaction.class);
//事务对应的数据库连接
  protected Connection connection;
  // 数据库连接所属的DataSource
  protected DataSource dataSource;
  // 事务隔离级别
  protected TransactionIsolationLevel level;
  // 是否自动提交
  protected boolean autoCommit;
}

TransactionFactory

public interface TransactionFactory {

  /**
   * Sets transaction factory custom properties.
   * @param props
   *          the new properties
   */
 // 完成对TransactionFactory的自定义配置
  default void setProperties(Properties props) {
    // NOP
  }

  /**
   * Creates a {@link Transaction} out of an existing connection.
   * @param conn Existing database connection
   * @return Transaction
   * @since 3.1.0
   */
 //在指定的连接上创建Transaction 对象
  Transaction newTransaction(Connection conn);

  /**
   * Creates a {@link Transaction} out of a datasource.
   * @param dataSource DataSource to take the connection from
   * @param level Desired isolation level
   * @param autoCommit Desired autocommit
   * @return Transaction
   * @since 3.1.0
   */
 //从指定数据源中获取数据库连接,并在此连接之上创建Transaction 对象
  Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);

}

binding 模块

MapperRegistry

/**
 * @author Clinton Begin
 * @author Eduardo Macarron
 * @author Lasse Voss
 * 是Mapper 接口及其对应的代理对象工厂的注册中心。
 */
public class MapperRegistry {
  //Configuration 对象,MyBatis 全局唯一的配置对象,其中包含了所有配置信息
  private final Configuration config;
 //记录了Mapper 接口与对应MapperProxyFactory 之间的关系
  private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();

  public MapperRegistry(Configuration config) {
    this.config = config;
  }

  @SuppressWarnings("unchecked")
  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    //查找指定type 对应的MapperProxyFactory 对象
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
    if (mapperProxyFactory == null) {
      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    }
    try {
      //创建实现了type 接口的代理对象
      return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {
      throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
  }

  public <T> boolean hasMapper(Class<T> type) {
    return knownMappers.containsKey(type);
  }

  public <T> void addMapper(Class<T> type) {
   //检测type 是否为接口
    if (type.isInterface()) {
     //检测是否已经加载过该接口
      if (hasMapper(type)) {
        throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
      }
      boolean loadCompleted = false;
      try {
       //将Mapper 接口对应的Class 对象和MapperProxyFactory 对象添加到knownMappers 集合
        knownMappers.put(type, new MapperProxyFactory<>(type));
        // It's important that the type is added before the parser is run
        // otherwise the binding may automatically be attempted by the
        // mapper parser. If the type is already known, it won't try.
        //XML 解析和注解的处理
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();
        loadCompleted = true;
      } finally {
        if (!loadCompleted) {
          knownMappers.remove(type);
        }
      }
    }
}  }

MapperProxyFactory

public class MapperProxyFactory<T> {
//当前MapperProxyFactory 对象可以创建实现了mapper Interface 接口的代理对象,
  private final Class<T> mapperInterface;
//缓存, key 是mapperinterface接口中某方法对应的Method 对象, value 是对应的MapperMethod对象
  private final Map<Method, MapperMethodInvoker> methodCache = new ConcurrentHashMap<>();

  public MapperProxyFactory(Class<T> mapperInterface) {
    this.mapperInterface = mapperInterface;
  }

  public Class<T> getMapperInterface() {
    return mapperInterface;
  }

  public Map<Method, MapperMethodInvoker> getMethodCache() {
    return methodCache;
  }

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
    //创建实现了mapperinterface 接口的代理对象
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  public T  newInstance(SqlSession sqlSession) {
    //创建MapperProxy 对象,每次调用都会创建新的MapperProxy 对象
    final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

}

MapperProxy

public class MapperProxy<T> implements InvocationHandler, Serializable {

  private static final long serialVersionUID = -4724728412955527868L;
  private static final int ALLOWED_MODES = MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED
      | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC;
  private static final Constructor<Lookup> lookupConstructor;
  private static final Method privateLookupInMethod;
  //记录了关联的SqlSession 对象
  private final SqlSession sqlSession;
  //Mapper 接口对应的Class 对象
  private final Class<T> mapperInterface;
  // 用于缓存MapperMethod 对象,其中key 是Mapper 接口中方法对应的Method 对象, value 是对应的
  // MapperMethod 对象。MapperMethod 对象会完成参数转换以及SQL 语句的执行功能
// 需要注意的是, MapperMethod 中并不记录任何状态相关的信息,所以可以在多个代理对象之间共享
  private final Map<Method, MapperMethodInvoker> methodCache;
@Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      //如果目标方法继承自Object ,则直接调用目标方法
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, args);
      } else {
        //从缓存中获取MapperMethod 对象,如缓存中没有,则创建新的MapperMethod 对象并添加到缓存中
        return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
  }
  }

MapperMethod

/**
 * @author Clinton Begin
 * @author Eduardo Macarron
 * @author Lasse Voss
 * @author Kazuki Shimizu
 * 封装了Mapper 接口中对应方法的信息,以及对应SQL 语句的信息
 */
public class MapperMethod {
  // 记录了SQL 语句的名称和类型
  private final SqlCommand command;
  // Mapper 接口中对应方法的相关信息
  private final MethodSignature method;
public static class SqlCommand {
    //记录SQL 语句的名称
    private final String name;
    //记录SQL 语句的类型
    private final SqlCommandType type;

    public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) {
      final String methodName = method.getName();
      final Class<?> declaringClass = method.getDeclaringClass();
      MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass,
          configuration);
      if (ms == null) {
        //处理@ Flush i主解
        if (method.getAnnotation(Flush.class) != null) {
          name = null;
          type = SqlCommandType.FLUSH;
        } else {
          throw new BindingException("Invalid bound statement (not found): "
              + mapperInterface.getName() + "." + methodName);
        }
      } else {
        //初始化name 和type
        name = ms.getId();
        type = ms.getSqlCommandType();
        if (type == SqlCommandType.UNKNOWN) {
          throw new BindingException("Unknown execution method for: " + name);
        }
      }
      }
private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName,
        Class<?> declaringClass, Configuration configuration) {
      // SQL 语句的名称是由Mapper 接口的名称与对应的方法名称组成的
      String statementId = mapperInterface.getName() + "." + methodName;
      //检测是否有该名称的SQL 语句
      if (configuration.hasStatement(statementId)) {
        //从Configuration.mappedStatements集合中查找对应的MappedStatement对象
        return configuration.getMappedStatement(statementId);
      } else if (mapperInterface.equals(declaringClass)) {
        return null;
      }
      //如果指定方法是在父接口中定义的, 则在此进行继承结构的处理
      for (Class<?> superInterface : mapperInterface.getInterfaces()) {
        if (declaringClass.isAssignableFrom(superInterface)) {
          MappedStatement ms = resolveMappedStatement(superInterface, methodName,
              declaringClass, configuration);
          if (ms != null) {
            return ms;
          }
        }
      }
      return null;
    }
}

 public static class MethodSignature {
//返回值类型是否为Collection 类型或是数组类型
    private final boolean returnsMany;
//返回值类型是否为Map类型
    private final boolean returnsMap;
//返回值类型是否为Void
    private final boolean returnsVoid;
    // 返回值是否为Cursor 类型
    private final boolean returnsCursor;
    private final boolean returnsOptional;
    // 返回值类型
    private final Class<?> returnType;
    //如果返回值类型是Map ,则该字段记录了作为key 的列名
    private final String mapKey;
    //用来标记该方法参数列表中ResultHandler 类型参数的位置
    private final Integer resultHandlerIndex;
    //用来标记该方法参数列表中RowBounds 类型参数的位置
    private final Integer rowBoundsIndex;
    //该方法对应的ParamNameResolver 对象
    private final ParamNameResolver paramNameResolver;

    public MethodSignature(Configuration configuration, Class<?> mapperInterface, Method method) {
      //解析方法的返回值类型
      Type resolvedReturnType = TypeParameterResolver.resolveReturnType(method, mapperInterface);
      if (resolvedReturnType instanceof Class<?>) {
        this.returnType = (Class<?>) resolvedReturnType;
      } else if (resolvedReturnType instanceof ParameterizedType) {
        this.returnType = (Class<?>) ((ParameterizedType) resolvedReturnType).getRawType();
      } else {
        this.returnType = method.getReturnType();
      }
      //初始化returnsVoid 、returnsMany 、returnsCursor 、map Key 、returnsMap 等字段
      this.returnsVoid = void.class.equals(this.returnType);
      this.returnsMany = configuration.getObjectFactory().isCollection(this.returnType) || this.returnType.isArray();
      this.returnsCursor = Cursor.class.equals(this.returnType);
      this.returnsOptional = Optional.class.equals(this.returnType);
      //若MethodSignature 对应方法的返回位是Map 且指定了@ Map Key注解,则使用getMapKey ()方法处理
      this.mapKey = getMapKey(method);
      this.returnsMap = this.mapKey != null;
      //初始化rowBoundsindex 和resultHandlerindex 字段
      this.rowBoundsIndex = getUniqueParamIndex(method, RowBounds.class);
      this.resultHandlerIndex = getUniqueParamIndex(method, ResultHandler.class);
      //创建ParamNameResolver 对象
      this.paramNameResolver = new ParamNameResolver(configuration, method);
    }
  //查找指定类型的参数在参数列表中的位置
    private Integer getUniqueParamIndex(Method method, Class<?> paramType) {
      Integer index = null;
      final Class<?>[] argTypes = method.getParameterTypes();
      for (int i = 0; i < argTypes.length; i++) {

        if (paramType.isAssignableFrom(argTypes[i])) {
          //记录paramType 类型参数在参数列表中的位置索引
          if (index == null) {
            index = i;
          } else {
            // RowBounds 和ResultHandler 类型的参数只能有一个,不能重复出现
            throw new BindingException(method.getName() + " cannot have multiple " + paramType.getSimpleName() + " parameters");
          }
        }
      }
      return index;
    }
//负责将args []数纽( 用户传入的实参列表)转换成SQL 语句对应的参数列表,
    public Object convertArgsToSqlCommandParam(Object[] args) {
      return paramNameResolver.getNamedParams(args);
    }
}

 //根据SQL 语句的类型调用SqI Session 对应的方法完成数据库操作。
  public Object execute(SqlSession sqlSession, Object[] args) {
    Object result;
    //根据SQL 语句的类型调用SqlSession 对应的方法
    switch (command.getType()) {
      case INSERT: {
        //使用ParamNameResolver处理args []数组(用户传入的实参列表),将用户传入的实参与指定参数名称关联起来
        Object param = method.convertArgsToSqlCommandParam(args);
        //调用SqlSession.insert ()方法, rowCountResult ()方法会根据method 字段中记录的方法的 返回值类型对结果进行转换
        result = rowCountResult(sqlSession.insert(command.getName(), param));
        break;
      }
      case UPDATE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.update(command.getName(), param));
        break;
      }
      case DELETE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.delete(command.getName(), param));
        break;
      }
      case SELECT:
        //处理返回值为void 且ResultSet 通过ResultHandler 处理的方法
        if (method.returnsVoid() && method.hasResultHandler()) {
          executeWithResultHandler(sqlSession, args);
          result = null;
        } else if (method.returnsMany()) {
          //处理返回值为集合或数组的方法
          result = executeForMany(sqlSession, args);
        } else if (method.returnsMap()) {
          //处理返回值为Map 的方法
          result = executeForMap(sqlSession, args);
        } else if (method.returnsCursor()) {
          // 处理返回值为Curs or 的方法
          result = executeForCursor(sqlSession, args);
        } else {
          //处理返回值为单一对象的方法
          Object param = method.convertArgsToSqlCommandParam(args);
          result = sqlSession.selectOne(command.getName(), param);
          if (method.returnsOptional()
              && (result == null || !method.getReturnType().equals(result.getClass()))) {
            result = Optional.ofNullable(result);
          }
        }
        break;
      case FLUSH:
        result = sqlSession.flushStatements();
        break;
      default:
        throw new BindingException("Unknown execution method for: " + command.getName());
    }
    if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
      throw new BindingException("Mapper method '" + command.getName()
          + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
    }
    return result;
  }

private Object rowCountResult(int rowCount) {
    final Object result;
    if (method.returnsVoid()) {
      //Mapper 接口中相应方法的返回值为void
      result = null;
    } else if (Integer.class.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType())) {
     // Mapper 接口中相应方法的返回值为int 或Integer
      result = rowCount;
    } else if (Long.class.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType())) {
      // Mapper 接口中相应方法的返回值为long 或Long
      result = (long) rowCount;
    } else if (Boolean.class.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType())) {
      // Mapper 接口中相应方法的返回值为boolean 或Boolean
      result = rowCount > 0;
    } else {
      throw new BindingException("Mapper method '" + command.getName() + "' has an unsupported return type: " + method.getReturnType());
    }
    return result;
  }
  //使用ResultHandler处理查询结果集
  private void executeWithResultHandler(SqlSession sqlSession, Object[] args) {
    //获取SQL 语句对应的MappedStatement 对象, MappedStatement 中记录了SQL 语句相关信息,
    MappedStatement ms = sqlSession.getConfiguration().getMappedStatement(command.getName());
    //当使用ResultHandler 处理结采集时,必须指定ResultMap 或ResultType
    if (!StatementType.CALLABLE.equals(ms.getStatementType())
        && void.class.equals(ms.getResultMaps().get(0).getType())) {
      throw new BindingException("method " + command.getName()
          + " needs either a @ResultMap annotation, a @ResultType annotation,"
          + " or a resultType attribute in XML so a ResultHandler can be used as a parameter.");
    }
    Object param = method.convertArgsToSqlCommandParam(args);
    //检测参数列表中是否有RowBounds 类型的参数
    if (method.hasRowBounds()) {
      //获取RowBounds对象,根据MethodSignature.rowBoundsindex 字段指定位置,从args 数组中 查找。获取ResultHandler 对象的原理相同
      RowBounds rowBounds = method.extractRowBounds(args);
      //调用SqlSession.select ()方法,执行查询,并由指定的ResultHandler 处理结果对象
      sqlSession.select(command.getName(), param, rowBounds, method.extractResultHandler(args));
    } else {
      sqlSession.select(command.getName(), param, method.extractResultHandler(args));
    }
  }

  private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
    List<E> result;
    //参数列表转换
    Object param = method.convertArgsToSqlCommandParam(args);
      //检测是否指定了RowBounds 参数
    if (method.hasRowBounds()) {
      RowBounds rowBounds = method.extractRowBounds(args);
      //调用SqlSession.selectList ()方法完成查询
      result = sqlSession.selectList(command.getName(), param, rowBounds);
    } else {
      result = sqlSession.selectList(command.getName(), param);
    }
    // issue #510 Collections & arrays support
    //将结果集转换为数组或Collection 集合
    if (!method.getReturnType().isAssignableFrom(result.getClass())) {
      if (method.getReturnType().isArray()) {
        return convertToArray(result);
      } else {
        return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
      }
    }
    return result;
  }

private <E> Object convertToDeclaredCollection(Configuration config, List<E> list) {
   //使用ObjectFactory ,通过反射方式创建集合对象
    Object collection = config.getObjectFactory().create(method.getReturnType());
   //创建MetaObject 对象
    MetaObject metaObject = config.newMetaObject(collection);
   //实际上就是调用Collection. addAll ()方法
    metaObject.addAll(list);
    return collection;
  }

  @SuppressWarnings("unchecked")
  private <E> Object convertToArray(List<E> list) {
    //获取数纽元素的类型
    Class<?> arrayComponentType = method.getReturnType().getComponentType();
    //创建数组对象
    Object array = Array.newInstance(arrayComponentType, list.size());
   //将list 中每一项都添加到数组中
    if (arrayComponentType.isPrimitive()) {
      for (int i = 0; i < list.size(); i++) {
        Array.set(array, i, list.get(i));
      }
      return array;
    } else {
      return list.toArray((E[]) array);
    }
  }

}

ParamNameResolver

public class ParamNameResolver {

 //记录参数在参数列表中的位置索引与参数名称之间的对应关系
  private final SortedMap<Integer, String> names;
  //记录对应方法的参数列表中是否使用了@Param 注解。
  private boolean hasParamAnnotation;

  public ParamNameResolver(Configuration config, Method method) {
    this.useActualParamName = config.isUseActualParamName();
   //获取参数列表中每个参数的类型
    final Class<?>[] paramTypes = method.getParameterTypes();
   //获取参数列表上的注解
    final Annotation[][] paramAnnotations = method.getParameterAnnotations();
   //该集合用于记录参数索引与参数名称的对应关系
    final SortedMap<Integer, String> map = new TreeMap<>();
    int paramCount = paramAnnotations.length;
    // get names from @Param annotations
    for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) {
     //如参数是RowBounds 类型或ResultHandler 类型,跳过对该参数的分析
      if (isSpecialParameter(paramTypes[paramIndex])) {
        // skip special parameters
        continue;
      }
      String name = null;
     // 遥历该参数对应的i主解集合
      for (Annotation annotation : paramAnnotations[paramIndex]) {
       // @Param出现过一次,就将hasParamAnnotation 初始化为true
        if (annotation instanceof Param) {
          hasParamAnnotation = true;
         //获取自Param注解指定的参数名称
          name = ((Param) annotation).value();
          break;
        }
      }
      if (name == null) {
        // @Param was not specified.
       //该参数没有对应的@Param注解,则根据配置决定是否使用参数实际名称作为其名称
        if (useActualParamName) {
          name = getActualParamName(method, paramIndex);
        }
        if (name == null) {
          // use the parameter index as the name ("0", "1", ...)
          // gcode issue #71
         //使用参数的索引作为其名称
          name = String.valueOf(map.size());
        }
      }
     // 记录到map 中保存
      map.put(paramIndex, name);
    }
   // 初始化names 集合
    names = Collections.unmodifiableSortedMap(map);
  }

  private String getActualParamName(Method method, int paramIndex) {
    return ParamNameUtil.getParamNames(method).get(paramIndex);
  }
  //isSpecialParameter ()方法用来过滤RowBounds 和ResultHandler 两种类型的参数
  private static boolean isSpecialParameter(Class<?> clazz) {
    return RowBounds.class.isAssignableFrom(clazz) || ResultHandler.class.isAssignableFrom(clazz);
  }

public Object getNamedParams(Object[] args) {
    final int paramCount = names.size();
    // 无参数,返回null
    if (args == null || paramCount == 0) {
      return null;
    } else if (!hasParamAnnotation && paramCount == 1) {
      // 未使用@Param且只有一个参数
      Object value = args[names.firstKey()];
      return wrapToMapIfCollection(value, useActualParamName ? names.get(0) : null);
    } else {
      //处理使用@Paramd主解指定了参数名称或有多个参数的情况
      // param这个Map中记录了参数名称与实参之间的对应关系。ParamMap继承了HashMap ,如果向
      // ParamMap 中添加已经存在的key ,会报错,其他行为与HashMap 相同
      final Map<String, Object> param = new ParamMap<>();
      int i = 0;
      for (Map.Entry<Integer, String> entry : names.entrySet()) {
        //将参数名与实参对应关系记录到pa ram 中
        param.put(entry.getValue(), args[entry.getKey()]);
        // add generic param names (param1, param2, ...)
        // 下面是为参数创建” param+索引”格式的默认参数名称,例如: paraml , param2等,并添加到param 集合中
        final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);
        // ensure not to overwrite parameter named with @Param
        //如@Param主解指定的参数名称就是” param+索引”格式的,则不需要再添加
        if (!names.containsValue(genericParamName)) {
          param.put(genericParamName, args[entry.getKey()]);
        }
        i++;
      }
      return param;
    }
  }

}

缓存

Cache

public interface Cache {

  /**
   * @return The identifier of this cache
   */
  // 该缓存对象的id
  String getId();

  /**
   * @param key
   *          Can be any object but usually it is a {@link CacheKey}
   * @param value
   *          The result of a select.
   */
  // 向缓存中添加数据,一般情况下, key 是Ca cheKey , value 是查询结果
  void putObject(Object key, Object value);

  /**
   * @param key
   *          The key
   * @return The object stored in the cache.
   */
  // 根据指定的key ,在缓存中查找对应的结果对象
  Object getObject(Object key);

  /**
   * As of 3.3.0 this method is only called during a rollback
   * for any previous value that was missing in the cache.
   * This lets any blocking cache to release the lock that
   * may have previously put on the key.
   * A blocking cache puts a lock when a value is null
   * and releases it when the value is back again.
   * This way other threads will wait for the value to be
   * available instead of hitting the database.
   *
   *
   * @param key
   *          The key
   * @return Not used
   */
  Object removeObject(Object key);

  /**
   * Clears this cache instance.
   */
  void clear();

  /**
   * Optional. This method is not called by the core.
   *
   * @return The number of elements stored in the cache (not its capacity).
   */
  //缓存项的个数,该方法不会被MyBatis 核心代码使用
  int getSize();

  /**
   * Optional. As of 3.2.6 this method is no longer called by the core.
   * <p>
   * Any locking needed by the cache must be provided internally by the cache provider.
   *
   * @return A ReadWriteLock
   */
  //获取读写锁,该方法不会被MyBatis 核心代码使用,所以可提供空实现
  default ReadWriteLock getReadWriteLock() {
    return null;
  }

}

在这里插入图片描述

PerpetualCache

public class PerpetualCache implements Cache {
  //Cache 对象的唯一标识
  private final String id;
//用于记录缓存项的Map 对象
  private final Map<Object, Object> cache = new HashMap<>();
  }

BlockingCache

/**
 * Simple blocking decorator
 *
 * Simple and inefficient version of EhCache's BlockingCache decorator.
 * It sets a lock over a cache key when the element is not found in cache.
 * This way, other threads will wait until this element is filled instead of hitting the database.
 *
 * @author Eduardo Macarron
 *
 * 阻塞版本的缓存装饰器,它会保证只有一个线程到数据库中查找指定key对应的数据
 */
public class BlockingCache implements Cache {
// 阻塞超时时长
  private long timeout;
  // 被装饰的底层Cache 对象
  private final Cache delegate;
  //每个key 都有对应的ReentrantLock 对象
  private final ConcurrentHashMap<Object, ReentrantLock> locks;

@Override
  public void putObject(Object key, Object value) {
    try {
      // 向缓存中添加缓存项
      delegate.putObject(key, value);
    } finally {
      //释放锁
      releaseLock(key);
    }
  }

  @Override
  public Object getObject(Object key) {
    //获取该key 对应的锁
    acquireLock(key);
    //查询key
    Object value = delegate.getObject(key);
    //缓存有key 对应的缓存项,择放锁,否则继续持有锁
    if (value != null) {
      releaseLock(key);
    }
    return value;
  }

  private void acquireLock(Object key) {
    //获取ReentrantLock 对象
    Lock lock = getLockForKey(key);
   //获取锁,带超时时长
    if (timeout > 0) {
      try {
        boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS);
        //超时,则抛出异常
        if (!acquired) {
          throw new CacheException("Couldn't get a lock in " + timeout + " for the key " +  key + " at the cache " + delegate.getId());
        }
      } catch (InterruptedException e) {
        throw new CacheException("Got interrupted while trying to acquire lock for key " + key, e);
      }
    } else {
      //获取锁,不带起时时长
      lock.lock();
    }
  }

  private void releaseLock(Object key) {
    ReentrantLock lock = locks.get(key);
    //锁是否被当前线程持有
    if (lock.isHeldByCurrentThread()) {
      //释放锁
      lock.unlock();
    }
  }

}


FifoCache

/**
 * FIFO (first in, first out) cache decorator.
 *先入先出版本的装饰器, 当向缓存添加数据时,如果缓存项的个数已经达到上限, 则会将缓存中
 * 最老( 即最早进入缓存) 的缓存项删除。
 * @author Clinton Begin
 */
public class FifoCache implements Cache {
//底层被装饰的底层Cache 对象
  private final Cache delegate;
// 用于记录key 进入缓存的先后顺序, 使用的是LinkedList <Object> 类型的集合对象
  private final Deque<Object> keyList;
//记录了缓存项的上限, 超过该值, 则需要清理最老的缓存项
  private int size;

 @Override
  public void putObject(Object key, Object value) {
    //检测并清理缓存
    cycleKeyList(key);
    // 添加缓存项
    delegate.putObject(key, value);
  }

  private void cycleKeyList(Object key) {
    // 记录key
    keyList.addLast(key);
    //如果达到缓存上限,则清理最老的缓存项
    if (keyList.size() > size) {
      Object oldestKey = keyList.removeFirst();
      delegate.removeObject(oldestKey);
    }
  }

}


LruCache

/**
 * Lru (least recently used) cache decorator.
 *按照近期最少使用算法( Least Recently Used, LRU )进行缓存清理的装饰器,
 * 在需要清理缓存时它会清除最近最少使用的缓存工页
 * @author Clinton Begin
 */
public class LruCache implements Cache {

// 被装饰的底层Cache 对象
  private final Cache delegate;
  // LinkedHashMap<Object,Object >类型对象,它是一个有序的HashMap ,用于记录key最近的使用情况
  private Map<Object, Object> keyMap;
// 记录最少被使用的缓存项的k ey
  private Object eldestKey;

  public LruCache(Cache delegate) {
    this.delegate = delegate;
    setSize(1024);
  }

  @Override
  public String getId() {
    return delegate.getId();
  }

  @Override
  public int getSize() {
    return delegate.getSize();
  }
//重新设置缓存大小时,会重置keyMap 字段
  public void setSize(final int size) {
   // true 表示该LinkedHashMap 记录的顺序是 access-order ,也就是说LinkedHashMap.get ()方法会改变其记录的顺序
    keyMap = new LinkedHashMap<Object, Object>(size, .75F, true) {
      private static final long serialVersionUID = 4267176411845948333L;

      @Override
      //当调用LinkedHashMap.put ()方法时,会调用该方法
      protected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {
        boolean tooBig = size() > size;
        //已到达缓存上限,则更新eldestKey 字段, 后面会删除该项
        if (tooBig) {
          eldestKey = eldest.getKey();
        }
        return tooBig;
      }
    };
  }

  @Override
  public void putObject(Object key, Object value) {
    //添加缓存项
    delegate.putObject(key, value);
    //删除最久未使用的缓存项
    cycleKeyList(key);
  }

  @Override
  public Object getObject(Object key) {
   //修改LinkedHashMap 中记录的顺序
    keyMap.get(key); // touch
    return delegate.getObject(key);
  }

  private void cycleKeyList(Object key) {
    keyMap.put(key, key);
    // eldestKey 不为空,表示已经达到缓存上眼
    if (eldestKey != null) {
      // 删除最久未使用的缓存项
      delegate.removeObject(eldestKey);
      eldestKey = null;
    }
  }

}

SoftCache

/**
 * Soft Reference cache decorator
 * Thanks to Dr. Heinz Kabutz for his guidance here.
 *
 * @author Clinton Begin
 */
public class SoftCache implements Cache {
  //在SoftCache中,最近使用的一部分缓存项不会被GC 回收,这就是通过将其value
  // 添加到hardLinksToAvoidGarbageCollection集合中实现的(即有强引用指向其value)
  // hardLinksToAvoidGarbageCollection集合是LinkedList<Object>类型
  private final Deque<Object> hardLinksToAvoidGarbageCollection;
 // ReferenceQueue 引用队列,用于记录已经被GC 回收的缓存项所对应的SoftEntry 对象
  private final ReferenceQueue<Object> queueOfGarbageCollectedEntries;
 // 底层被装饰的底层Cache 对象
  private final Cache delegate;
  // 强连接的个数, 默认值是256
  private int numberOfHardLinks;

  public SoftCache(Cache delegate) {
    this.delegate = delegate;
    this.numberOfHardLinks = 256;
    this.hardLinksToAvoidGarbageCollection = new LinkedList<>();
    this.queueOfGarbageCollectedEntries = new ReferenceQueue<>();
  }


  @Override
  /**
   * 向缓存中添加缓存项
   * 还会清除己经被GC回收的缓存项,
   */
  public void putObject(Object key, Object value) {
   // 清除已经被GC 回收的缓存项
    removeGarbageCollectedItems();
    //向缓存中添加缓存项
    delegate.putObject(key, new SoftEntry(key, value, queueOfGarbageCollectedEntries));
  }

  @Override
  /**
   * 从缓存中查找对应的value ,
   * 处理被GC 回收的value对应的缓存项,
   * 还会更新hardLinksToAvoidGarbageCollection 集合
   */
  public Object getObject(Object key) {
    Object result = null;
    @SuppressWarnings("unchecked") // assumed delegate cache is totally managed by this cache
      //从缓存中查找对应的缓存项
    SoftReference<Object> softReference = (SoftReference<Object>) delegate.getObject(key);
    //检测缓存中是否有对应的缓存项
    if (softReference != null) {
      //获取SoftRef erence 引用的value
      result = softReference.get();
      // 已经被GC 回收
      if (result == null) {
       //从缓存中清除对应的缓存项
        delegate.removeObject(key);
      } else {
        //未被GC 回收
        // See #586 (and #335) modifications need more than a read lock
        synchronized (hardLinksToAvoidGarbageCollection) {
        //缓存项的value 添加到hardLinksToAvoidGarbageCollection 集合中保存
          hardLinksToAvoidGarbageCollection.addFirst(result);
        //超过nurnberOfHardLinks ,则将最老的缓存项从hardLinksToAvoidGarbageCollection 集合中清除,有点类似于先进先出队列
          if (hardLinksToAvoidGarbageCollection.size() > numberOfHardLinks) {
            hardLinksToAvoidGarbageCollection.removeLast();
          }
        }
      }
    }
    return result;
  }

  @Override
  public Object removeObject(Object key) {
    removeGarbageCollectedItems();
    return delegate.removeObject(key);
  }

  @Override
  public void clear() {
    synchronized (hardLinksToAvoidGarbageCollection) {
      //清理强引用集合
      hardLinksToAvoidGarbageCollection.clear();
    }
    //清理被GC 回收的缓存项
    removeGarbageCollectedItems();
    //清理底层delegate 缓存中的缓存项
    delegate.clear();
  }

  private void removeGarbageCollectedItems() {
    SoftEntry sv;
    //遍历queueOfGarbageCollectedEntries 集合
    while ((sv = (SoftEntry) queueOfGarbageCollectedEntries.poll()) != null) {
     // 将已经被GC 回收的value 对象对应的缓存项清除
      delegate.removeObject(sv.key);
    }
  }

/*
SoftReference:当Java虚拟机内存不足时, GC 会回收那些只被软引用指向的对象,从而避免内存溢出
*/
  private static class SoftEntry extends SoftReference<Object> {
    private final Object key;

    SoftEntry(Object key, Object value, ReferenceQueue<Object> garbageCollectionQueue) {
      // 指向value的引用是软引用,且关联了引用队列
      super(value, garbageCollectionQueue);
      // 强引用
      this.key = key;
    }
  }

}

ScheduledCache

/**
 * 周期性清理缓存的装饰器
 * @author Clinton Begin
 */
public class ScheduledCache implements Cache {

  private final Cache delegate;
  //记录两次缓存清理之间的时间间隔,默认是一小时
  protected long clearInterval;
 // 记录最近一次清理的时间戳
  protected long lastClear;
  }

CacheKey

ublic class CacheKey implements Cloneable, Serializable {

  private static final long serialVersionUID = 1146682552656046210L;

  public static final CacheKey NULL_CACHE_KEY = new CacheKey() {

    @Override
    public void update(Object object) {
      throw new CacheException("Not allowed to update a null cache key instance.");
    }

    @Override
    public void updateAll(Object[] objects) {
      throw new CacheException("Not allowed to update a null cache key instance.");
    }
  };

  private static final int DEFAULT_MULTIPLIER = 37;
  private static final int DEFAULT_HASHCODE = 17;
//参与计算hashcode ,默认位是37
  private final int multiplier;
  // CacheKey 对象的hashcode ,初始位是17
  private int hashcode;
  //校验和
  private long checksum;
  // updateList 集合的个数
  private int count;
  // 8/21/2017 - Sonarlint flags this as needing to be marked transient. While true if content is not serializable, this
  // is not always true and thus should not be marked transient.
  //由该集合中的所有对象共同决定两个CacheKey 是否相同
  /*
  updateList集合值
  MappedStatement的id 。
指定查询结果集的范围,也就是RowBounds .offset 和RowBounds.limit 。
查询所使用的SQL 语句,也就是boundSql.getSql ()方法返回的SQL 语句,其中可能包含“?”占位符。
用户传递给上述SQL 语句的实际参数值。
   */
  private List<Object> updateList;
 @Override
  public boolean equals(Object object) {
    //是否走向一对象
    if (this == object) {
      return true;
    }
    // 是否类型相同
    if (!(object instanceof CacheKey)) {
      return false;
    }

    final CacheKey cacheKey = (CacheKey) object;

    // 比较hashcode
    if (hashcode != cacheKey.hashcode) {
      return false;
    }
    //比较checksum
    if (checksum != cacheKey.checksum) {
      return false;
    }
    // 比较count
    if (count != cacheKey.count) {
      return false;
    }
    // 比较updateList 中每一项
    for (int i = 0; i < updateList.size(); i++) {
      Object thisObject = updateList.get(i);
      Object thatObject = cacheKey.updateList.get(i);
      if (!ArrayUtil.equals(thisObject, thatObject)) {
        return false;
      }
    }
    return true;
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值