经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MyBatis » 查看文章
Mybatis框架基础支持层——反射工具箱之MetaClass(7)
来源:cnblogs  作者:^^ITBOY^^  时间:2019/1/30 9:26:44  对本文有异议

简介:MetaClass是Mybatis对类级别的元信息的封装和处理,通过与属性工具类的结合, 实现了对复杂表达式的解析,实现了获取指定描述信息的功能

  1. public class MetaClass {
  2. private ReflectorFactory reflectorFactory;
  3. private Reflector reflector;
  4. /**
  5. * 构造函数私有
  6. */
  7. private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) {
  8. this.reflectorFactory = reflectorFactory;
  9. this.reflector = reflectorFactory.findForClass(type);
  10. }
  11. /**
  12. * 调用构造方法创建MetaClass
  13. */
  14. public static MetaClass forClass(Class<?> type, ReflectorFactory reflectorFactory) {
  15. return new MetaClass(type, reflectorFactory);
  16. }
  17. /**
  18. * 通过属性名称, 获取属性的MetaClass(解决成员变量是类的情况)
  19. */
  20. public MetaClass metaClassForProperty(String name) {
  21. Class<?> propType = reflector.getGetterType(name);
  22. return MetaClass.forClass(propType, reflectorFactory);
  23. }
  24. public String findProperty(String name) {
  25. StringBuilder prop = buildProperty(name, new StringBuilder());
  26. return prop.length() > 0 ? prop.toString() : null;
  27. }
  28. public String findProperty(String name, boolean useCamelCaseMapping) {
  29. if (useCamelCaseMapping) {
  30. name = name.replace("_", "");
  31. }
  32. return findProperty(name);
  33. }
  34. public String[] getGetterNames() {
  35. return reflector.getGetablePropertyNames();
  36. }
  37. public String[] getSetterNames() {
  38. return reflector.getSetablePropertyNames();
  39. }
  40. public Class<?> getSetterType(String name) {
  41. PropertyTokenizer prop = new PropertyTokenizer(name);
  42. if (prop.hasNext()) {
  43. MetaClass metaProp = metaClassForProperty(prop.getName());
  44. return metaProp.getSetterType(prop.getChildren());
  45. } else {
  46. return reflector.getSetterType(prop.getName());
  47. }
  48. }
  49. public Class<?> getGetterType(String name) {
  50. PropertyTokenizer prop = new PropertyTokenizer(name);
  51. if (prop.hasNext()) {
  52. MetaClass metaProp = metaClassForProperty(prop);
  53. return metaProp.getGetterType(prop.getChildren());
  54. }
  55. // issue #506. Resolve the type inside a Collection Object
  56. return getGetterType(prop);
  57. }
  58. private MetaClass metaClassForProperty(PropertyTokenizer prop) {
  59. Class<?> propType = getGetterType(prop);
  60. return MetaClass.forClass(propType, reflectorFactory);
  61. }
  62. private Class<?> getGetterType(PropertyTokenizer prop) {
  63. Class<?> type = reflector.getGetterType(prop.getName());
  64. if (prop.getIndex() != null && Collection.class.isAssignableFrom(type)) {
  65. Type returnType = getGenericGetterType(prop.getName());
  66. if (returnType instanceof ParameterizedType) {
  67. Type[] actualTypeArguments = ((ParameterizedType) returnType).getActualTypeArguments();
  68. if (actualTypeArguments != null && actualTypeArguments.length == 1) {
  69. returnType = actualTypeArguments[0];
  70. if (returnType instanceof Class) {
  71. type = (Class<?>) returnType;
  72. } else if (returnType instanceof ParameterizedType) {
  73. type = (Class<?>) ((ParameterizedType) returnType).getRawType();
  74. }
  75. }
  76. }
  77. }
  78. return type;
  79. }
  80. private Type getGenericGetterType(String propertyName) {
  81. try {
  82. Invoker invoker = reflector.getGetInvoker(propertyName);
  83. if (invoker instanceof MethodInvoker) {
  84. Field _method = MethodInvoker.class.getDeclaredField("method");
  85. _method.setAccessible(true);
  86. Method method = (Method) _method.get(invoker);
  87. return TypeParameterResolver.resolveReturnType(method, reflector.getType());
  88. } else if (invoker instanceof GetFieldInvoker) {
  89. Field _field = GetFieldInvoker.class.getDeclaredField("field");
  90. _field.setAccessible(true);
  91. Field field = (Field) _field.get(invoker);
  92. return TypeParameterResolver.resolveFieldType(field, reflector.getType());
  93. }
  94. } catch (NoSuchFieldException e) {
  95. } catch (IllegalAccessException e) {
  96. }
  97. return null;
  98. }
  99. public boolean hasSetter(String name) {
  100. PropertyTokenizer prop = new PropertyTokenizer(name);
  101. if (prop.hasNext()) {
  102. if (reflector.hasSetter(prop.getName())) {
  103. MetaClass metaProp = metaClassForProperty(prop.getName());
  104. return metaProp.hasSetter(prop.getChildren());
  105. } else {
  106. return false;
  107. }
  108. } else {
  109. return reflector.hasSetter(prop.getName());
  110. }
  111. }
  112. public boolean hasGetter(String name) {
  113. PropertyTokenizer prop = new PropertyTokenizer(name);
  114. if (prop.hasNext()) {
  115. if (reflector.hasGetter(prop.getName())) {
  116. MetaClass metaProp = metaClassForProperty(prop);
  117. return metaProp.hasGetter(prop.getChildren());
  118. } else {
  119. return false;
  120. }
  121. } else {
  122. return reflector.hasGetter(prop.getName());
  123. }
  124. }
  125. public Invoker getGetInvoker(String name) {
  126. return reflector.getGetInvoker(name);
  127. }
  128. public Invoker getSetInvoker(String name) {
  129. return reflector.getSetInvoker(name);
  130. }
  131. /**
  132. * 解析属性表达式 会去寻找reflector中是否有对应的的属性
  133. */
  134. private StringBuilder buildProperty(String name, StringBuilder builder) {
  135. // 解析属性表达式
  136. PropertyTokenizer prop = new PropertyTokenizer(name);
  137. // 是否有子表达式
  138. if (prop.hasNext()) {
  139. // 查找对应的属性
  140. String propertyName = reflector.findPropertyName(prop.getName());
  141. if (propertyName != null) {
  142. // 追加属性名
  143. builder.append(propertyName);
  144. builder.append(".");
  145. // 创建对应的 MetaClass 对象
  146. MetaClass metaProp = metaClassForProperty(propertyName);
  147. // 解析子表达式, 递归
  148. metaProp.buildProperty(prop.getChildren(), builder);
  149. }
  150. } else {
  151. // 根据名称查找属性
  152. String propertyName = reflector.findPropertyName(name);
  153. if (propertyName != null) {
  154. builder.append(propertyName);
  155. }
  156. }
  157. return builder;
  158. }
  159. public boolean hasDefaultConstructor() {
  160. return reflector.hasDefaultConstructor();
  161. }
  162. }

理解了这个方法(递归, 该类中有很多类似的), 就可以很好的对这个类进行理解, 以查找(richType.richProperty)为例:

  1. 通过 PropertyTokenizer 对表达式进行解析, 得到当前的 name = richType,  children = richProperty
  2. 从 reflector 中查找该 richType 属性
  3. 将 richType 添加到 builder 中
  4. 使用 metaClassForProperty 创建 richType 的 MetaClass。
  5. 递归调用自身来处理子表达式

退出的条件就是没有子表达式。 这个就是为了, 我们类中有成员变量是类, 我们可以通过其找到他们的所有类及其属性
注意, 在此过程中, ReflectorFactory 一直是同一个, 而其内部缓存了多个 Reflector 对象。

原文链接:http://www.cnblogs.com/wly1-6/p/10333917.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号