内容简介:Mybatis在进行参数处理、结果映射等操作时,会涉及很多反射的操作。Mybatis源码中的对应反射模块的部分叫做Reflector.首先我们先分清属性和字段这两个概念:下面我们就开始分析这个反射模块(注意:下面分析的源码的Mybatis的版本是3.4.6,如果有什么错误,欢迎大家在评论指出):源码图示
Mybatis在进行参数处理、结果映射等操作时,会涉及很多反射的操作。Mybatis源码中的对应反射模块的部分叫做Reflector.首先我们先分清属性和字段这两个概念:
- 字段----类中定义的成员变量
- 属性----属性则是通过Getter和Setter方法获得的,跟有没有这个成员变量没有关系。
下面我们就开始分析这个反射模块(注意:下面分析的源码的Mybatis的版本是3.4.6,如果有什么错误,欢迎大家在评论指出):
字段
构造函数
- type :初始化type字段
- addDefaultConstructor ():获取默认构造函数。
- addGetMethods():处理目标class中的Getter方法,填充getMethods和getTypes字段。
- addSetMethods():处理目标class中的Setter方法,填充setMethods和setTypes字段。
- addFields():处理目标class中没有Getter和Setter方法的字段。
- caseInsensitivePropertyMap:初始化caseinsensitivePropertyMap集合,其中记录了所有大写格式的属性名称。
addGetMethods()
源码图示
大致流程:
- 首先获取当前目标类及其父类的定义的所有方法的唯一签名及其Method对象,对应的方法为getClassMethods()
- 当子类覆盖了父类的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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 以太坊源码分析(36)ethdb源码分析
- [源码分析] kubelet源码分析(一)之 NewKubeletCommand
- libmodbus源码分析(3)从机(服务端)功能源码分析
- [源码分析] nfs-client-provisioner源码分析
- [源码分析] kubelet源码分析(三)之 Pod的创建
- Spring事务源码分析专题(一)JdbcTemplate使用及源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Smashing Book
Jacob Gube、Dmitry Fadeev、Chris Spooner、Darius A Monsef IV、Alessandro Cattaneo、Steven Snell、David Leggett、Andrew Maier、Kayla Knight、Yves Peters、René Schmidt、Smashing Magazine editorial team、Vitaly Friedman、Sven Lennartz / 2009 / $ 29.90 / € 23.90
The Smashing Book is a printed book about best practices in modern Web design. The book shares technical tips and best practices on coding, usability and optimization and explores how to create succes......一起来看看 《The Smashing Book》 这本书的介绍吧!