Mybatis源码分析篇------Reflector

栏目: 数据库 · 发布时间: 4年前

内容简介:Mybatis在进行参数处理、结果映射等操作时,会涉及很多反射的操作。Mybatis源码中的对应反射模块的部分叫做Reflector.首先我们先分清属性和字段这两个概念:下面我们就开始分析这个反射模块(注意:下面分析的源码的Mybatis的版本是3.4.6,如果有什么错误,欢迎大家在评论指出):源码图示

Mybatis在进行参数处理、结果映射等操作时,会涉及很多反射的操作。Mybatis源码中的对应反射模块的部分叫做Reflector.首先我们先分清属性和字段这两个概念:

  • 字段----类中定义的成员变量
  • 属性----属性则是通过Getter和Setter方法获得的,跟有没有这个成员变量没有关系。

下面我们就开始分析这个反射模块(注意:下面分析的源码的Mybatis的版本是3.4.6,如果有什么错误,欢迎大家在评论指出):

字段

Mybatis源码分析篇------Reflector

构造函数

Mybatis源码分析篇------Reflector
  • type :初始化type字段
  • addDefaultConstructor ():获取默认构造函数。
  • addGetMethods():处理目标class中的Getter方法,填充getMethods和getTypes字段。
  • addSetMethods():处理目标class中的Setter方法,填充setMethods和setTypes字段。
  • addFields():处理目标class中没有Getter和Setter方法的字段。
  • caseInsensitivePropertyMap:初始化caseinsensitivePropertyMap集合,其中记录了所有大写格式的属性名称。

addGetMethods()

源码图示

Mybatis源码分析篇------Reflector

大致流程:

  1. 首先获取当前目标类及其父类的定义的所有方法的唯一签名及其Method对象,对应的方法为getClassMethods()
    Mybatis源码分析篇------Reflector
Mybatis源码分析篇------Reflector
Mybatis源码分析篇------Reflector
  1. 当子类覆盖了父类的Getter方法且返回值发生了变化,在第1步就会出现两个不同的签名,这显然不符合我们的预期要求。所有便会调用resolveGetterConflicts()方法解决冲突
private void resolveGetterConflicts(Map> conflictingGetters) {
    for (Entry> entry : conflictingGetters.entrySet()) {
      Method winner = null;
      String propName = entry.getKey();
      for (Method candidate : entry.getValue()) {
        if (winner == null) {
          winner = candidate;
          continue;
        }
        Class winnerType = winner.getReturnType();
        Class candidateType = candidate.getReturnType();
        if (candidateType.equals(winnerType)) {
          if (!boolean.class.equals(candidateType)) {
            throw new ReflectionException(
                "Illegal overloaded getter method with ambiguous type for property "
                    + propName + " in class " + winner.getDeclaringClass()
                    + ". This breaks the JavaBeans specification and can cause unpredictable results.");
          } else if (candidate.getName().startsWith("is")) {
            winner = candidate;
          }
        } else if (candidateType.isAssignableFrom(winnerType)) {
          // OK getter type is descendant
        } else if (winnerType.isAssignableFrom(candidateType)) {
          winner = candidate;
        } else {
          throw new ReflectionException(
              "Illegal overloaded getter method with ambiguous type for property "
                  + propName + " in class " + winner.getDeclaringClass()
                  + ". This breaks the JavaBeans specification and can cause unpredictable results.");
        }
      }
      addGetMethod(propName, winner);
    }
  }

addSetMethods() 逻辑与 addGetMethods() 差不多,我就不在重复叙述了。

addFields()会将这些没有get set方法的字段添加到 setMethods() getMethods()的集合中,逻辑如下面:

private void addFields(Class clazz) {
        //获取目标class中的全部字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (canAccessPrivateMethods()) {
                try {
                    field.setAccessible(true);
                } catch (Exception e) {

                }
            }
            if (field.isAccessible()) {
                //判断在setmethod 中是否已经处在有这个属性了
                if (!setMethods.containsKey(field.getName())) {
                    int modifiers = field.getModifiers();
                    if (!(Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers))) {
                        //如果这个属性不是Final或者静态,将其添加在setmethod和settype中
                        addSetField(field);
                    }
                }
                if (!getMethods.containsKey(field.getName())) {
                    //如果这个属性不是Final或者静态,将其添加在getmethod和gettype中
                    addGetField(field);
                }
            }
        }
        //检查是否有父类,继续递归执行该过程
        if (clazz.getSuperclass() != null) {
            addFields(clazz.getSuperclass());
        }
    }

以上所述就是小编给大家介绍的《Mybatis源码分析篇------Reflector》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Single Page Web Applications

Single Page Web Applications

Michael Mikowski、Josh Powell / Manning Publications / 2013-9-30 / USD 44.99

Code for most web sites mostly runs on the server. When a user clicks on a link, the site reacts slowly because the browser sends information to the server and the server sends it back again before di......一起来看看 《Single Page Web Applications》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

html转js在线工具
html转js在线工具

html转js在线工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具