Mybatis ObjectWrapper

  • Author: HuiFer
  • 源码阅读工程: SourceHot-Mybatis
  • 源码位于: org.apache.ibatis.reflection.wrapper.ObjectWrapper

类图:

image-20191223100956713

  1. public interface ObjectWrapper {
  2. /**
  3. * 根据 prop 获取属性值
  4. *
  5. * @param prop
  6. * @return
  7. */
  8. Object get(PropertyTokenizer prop);
  9. /**
  10. * 设置属性
  11. *
  12. * @param prop 属性值名称
  13. * @param value 属性值
  14. */
  15. void set(PropertyTokenizer prop, Object value);
  16. /**
  17. * 获取属性
  18. *
  19. * @param name
  20. * @param useCamelCaseMapping
  21. * @return
  22. */
  23. String findProperty(String name, boolean useCamelCaseMapping);
  24. /**
  25. * get 方法名,可读方法名
  26. *
  27. * @return
  28. */
  29. String[] getGetterNames();
  30. /**
  31. * set 方法名,可写方法名
  32. *
  33. * @return
  34. */
  35. String[] getSetterNames();
  36. /**
  37. * set 数据类型, 获取可写的数据类型
  38. *
  39. * @param name
  40. * @return
  41. */
  42. Class<?> getSetterType(String name);
  43. /**
  44. * get 数据类型, 获取可读的数据类型
  45. *
  46. * @param name
  47. * @return
  48. */
  49. Class<?> getGetterType(String name);
  50. /**
  51. * 判断是否包含set方法
  52. *
  53. * @param name
  54. * @return
  55. */
  56. boolean hasSetter(String name);
  57. /**
  58. * 判断是否包含get方法
  59. *
  60. * @param name
  61. * @return
  62. */
  63. boolean hasGetter(String name);
  64. /**
  65. * 初始化数据
  66. *
  67. * @param name
  68. * @param prop
  69. * @param objectFactory
  70. * @return
  71. */
  72. MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory);
  73. /**
  74. * 判断是不是 list
  75. *
  76. * @return
  77. */
  78. boolean isCollection();
  79. /**
  80. * list add
  81. *
  82. * @param element
  83. */
  84. void add(Object element);
  85. /**
  86. * list addAll
  87. *
  88. * @param element
  89. * @param <E>
  90. */
  91. <E> void addAll(List<E> element);
  92. }

BaseWrapper

  1. /**
  2. * @author Clinton Begin
  3. */
  4. public abstract class BaseWrapper implements ObjectWrapper {
  5. protected static final Object[] NO_ARGUMENTS = new Object[0];
  6. protected final MetaObject metaObject;
  7. protected BaseWrapper(MetaObject metaObject) {
  8. this.metaObject = metaObject;
  9. }
  10. /**
  11. * 处理集合对象
  12. * @param prop
  13. * @param object
  14. * @return
  15. */
  16. protected Object resolveCollection(PropertyTokenizer prop, Object object) {
  17. if ("".equals(prop.getName())) {
  18. return object;
  19. } else {
  20. return metaObject.getValue(prop.getName());
  21. }
  22. }
  23. /**
  24. * 对象获取,根据index
  25. * map.get(index)
  26. * 数组 array[index]
  27. * list list.get(index)
  28. * @param prop
  29. * @param collection
  30. * @return
  31. */
  32. protected Object getCollectionValue(PropertyTokenizer prop, Object collection) {
  33. if (collection instanceof Map) {
  34. // 如果是Map类型,则index为key
  35. return ((Map) collection).get(prop.getIndex());
  36. } else {
  37. // index 作为下标直接获取
  38. int i = Integer.parseInt(prop.getIndex());
  39. if (collection instanceof List) {
  40. return ((List) collection).get(i);
  41. } else if (collection instanceof Object[]) {
  42. return ((Object[]) collection)[i];
  43. } else if (collection instanceof char[]) {
  44. return ((char[]) collection)[i];
  45. } else if (collection instanceof boolean[]) {
  46. return ((boolean[]) collection)[i];
  47. } else if (collection instanceof byte[]) {
  48. return ((byte[]) collection)[i];
  49. } else if (collection instanceof double[]) {
  50. return ((double[]) collection)[i];
  51. } else if (collection instanceof float[]) {
  52. return ((float[]) collection)[i];
  53. } else if (collection instanceof int[]) {
  54. return ((int[]) collection)[i];
  55. } else if (collection instanceof long[]) {
  56. return ((long[]) collection)[i];
  57. } else if (collection instanceof short[]) {
  58. return ((short[]) collection)[i];
  59. } else {
  60. throw new ReflectionException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
  61. }
  62. }
  63. }
  64. /**
  65. * 设置属性值 ,List , object[] , char[] boolean byte double float int long short
  66. * map -> put(index,value)
  67. * list -> list.set(index,value)
  68. * array -> array[index] = value
  69. * @param prop
  70. * @param collection
  71. * @param value
  72. */
  73. protected void setCollectionValue(PropertyTokenizer prop, Object collection, Object value) {
  74. if (collection instanceof Map) {
  75. // map -> index:value
  76. ((Map) collection).put(prop.getIndex(), value);
  77. } else {
  78. // 数组 -> array[index]=value
  79. int i = Integer.parseInt(prop.getIndex());
  80. if (collection instanceof List) {
  81. ((List) collection).set(i, value);
  82. } else if (collection instanceof Object[]) {
  83. ((Object[]) collection)[i] = value;
  84. } else if (collection instanceof char[]) {
  85. ((char[]) collection)[i] = (Character) value;
  86. } else if (collection instanceof boolean[]) {
  87. ((boolean[]) collection)[i] = (Boolean) value;
  88. } else if (collection instanceof byte[]) {
  89. ((byte[]) collection)[i] = (Byte) value;
  90. } else if (collection instanceof double[]) {
  91. ((double[]) collection)[i] = (Double) value;
  92. } else if (collection instanceof float[]) {
  93. ((float[]) collection)[i] = (Float) value;
  94. } else if (collection instanceof int[]) {
  95. ((int[]) collection)[i] = (Integer) value;
  96. } else if (collection instanceof long[]) {
  97. ((long[]) collection)[i] = (Long) value;
  98. } else if (collection instanceof short[]) {
  99. ((short[]) collection)[i] = (Short) value;
  100. } else {
  101. throw new ReflectionException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
  102. }
  103. }
  104. }
  105. }

BeanWrapper

  1. public class BeanWrapper extends BaseWrapper {
  2. private final Object object;
  3. private final MetaClass metaClass;
  4. /**
  5. * 构造
  6. * @param metaObject
  7. * @param object
  8. */
  9. public BeanWrapper(MetaObject metaObject, Object object) {
  10. super(metaObject);
  11. this.object = object;
  12. this.metaClass = MetaClass.forClass(object.getClass(), metaObject.getReflectorFactory());
  13. }
  14. @Override
  15. public Object get(PropertyTokenizer prop) {
  16. // 索引不为空
  17. if (prop.getIndex() != null) {
  18. // 实例化集合对象
  19. Object collection = resolveCollection(prop, object);
  20. return getCollectionValue(prop, collection);
  21. } else {
  22. // 没有索引
  23. return getBeanProperty(prop, object);
  24. }
  25. }
  26. @Override
  27. public void set(PropertyTokenizer prop, Object value) {
  28. // 是否存在索引
  29. if (prop.getIndex() != null) {
  30. Object collection = resolveCollection(prop, object);
  31. // 向上层调用 BaseWrapper
  32. setCollectionValue(prop, collection, value);
  33. } else {
  34. // 本类方法
  35. setBeanProperty(prop, object, value);
  36. }
  37. }
  38. @Override
  39. public String findProperty(String name, boolean useCamelCaseMapping) {
  40. return metaClass.findProperty(name, useCamelCaseMapping);
  41. }
  42. @Override
  43. public String[] getGetterNames() {
  44. return metaClass.getGetterNames();
  45. }
  46. @Override
  47. public String[] getSetterNames() {
  48. return metaClass.getSetterNames();
  49. }
  50. @Override
  51. public Class<?> getSetterType(String name) {
  52. PropertyTokenizer prop = new PropertyTokenizer(name);
  53. if (prop.hasNext()) {
  54. MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
  55. // 是否null
  56. if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
  57. return metaClass.getSetterType(name);
  58. } else {
  59. return metaValue.getSetterType(prop.getChildren());
  60. }
  61. } else {
  62. return metaClass.getSetterType(name);
  63. }
  64. }
  65. @Override
  66. public Class<?> getGetterType(String name) {
  67. PropertyTokenizer prop = new PropertyTokenizer(name);
  68. if (prop.hasNext()) {
  69. MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
  70. if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
  71. return metaClass.getGetterType(name);
  72. } else {
  73. return metaValue.getGetterType(prop.getChildren());
  74. }
  75. } else {
  76. return metaClass.getGetterType(name);
  77. }
  78. }
  79. @Override
  80. public boolean hasSetter(String name) {
  81. PropertyTokenizer prop = new PropertyTokenizer(name);
  82. if (prop.hasNext()) {
  83. if (metaClass.hasSetter(prop.getIndexedName())) {
  84. MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
  85. if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
  86. return metaClass.hasSetter(name);
  87. } else {
  88. return metaValue.hasSetter(prop.getChildren());
  89. }
  90. } else {
  91. return false;
  92. }
  93. } else {
  94. return metaClass.hasSetter(name);
  95. }
  96. }
  97. /**
  98. * 是否包含 name 的get 方法
  99. * @param name
  100. * @return
  101. */
  102. @Override
  103. public boolean hasGetter(String name) {
  104. PropertyTokenizer prop = new PropertyTokenizer(name);
  105. if (prop.hasNext()) {
  106. if (metaClass.hasGetter(prop.getIndexedName())) {
  107. MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
  108. if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
  109. return metaClass.hasGetter(name);
  110. } else {
  111. return metaValue.hasGetter(prop.getChildren());
  112. }
  113. } else {
  114. return false;
  115. }
  116. } else {
  117. return metaClass.hasGetter(name);
  118. }
  119. }
  120. /**
  121. * 数据嵌套处理 a.b.c 需要处理成 a->b->c
  122. * @param name
  123. * @param prop
  124. * @param objectFactory
  125. * @return
  126. */
  127. @Override
  128. public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
  129. MetaObject metaValue;
  130. Class<?> type = getSetterType(prop.getName());
  131. try {
  132. Object newObject = objectFactory.create(type);
  133. // 出现嵌套处理 instantiatePropertyValue->set
  134. metaValue = MetaObject.forObject(newObject, metaObject.getObjectFactory(), metaObject.getObjectWrapperFactory(), metaObject.getReflectorFactory());
  135. set(prop, newObject);
  136. } catch (Exception e) {
  137. throw new ReflectionException("Cannot set value of property '" + name + "' because '" + name + "' is null and cannot be instantiated on instance of " + type.getName() + ". Cause:" + e.toString(), e);
  138. }
  139. return metaValue;
  140. }
  141. /**
  142. * 获取 object 的 prop 属性值
  143. * @param prop
  144. * @param object
  145. * @return
  146. */
  147. private Object getBeanProperty(PropertyTokenizer prop, Object object) {
  148. try {
  149. // 获取get 方法
  150. Invoker method = metaClass.getGetInvoker(prop.getName());
  151. try {
  152. // 获取属性值
  153. return method.invoke(object, NO_ARGUMENTS);
  154. } catch (Throwable t) {
  155. throw ExceptionUtil.unwrapThrowable(t);
  156. }
  157. } catch (RuntimeException e) {
  158. throw e;
  159. } catch (Throwable t) {
  160. throw new ReflectionException("Could not get property '" + prop.getName() + "' from " + object.getClass() + ". Cause: " + t.toString(), t);
  161. }
  162. }
  163. /**
  164. * 设置 object 的属性 prop 值为 value
  165. * @param prop
  166. * @param object
  167. * @param value
  168. */
  169. private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) {
  170. try {
  171. // 获取set 方法
  172. Invoker method = metaClass.getSetInvoker(prop.getName());
  173. Object[] params = {value};
  174. try {
  175. // 设置属性
  176. method.invoke(object, params);
  177. } catch (Throwable t) {
  178. throw ExceptionUtil.unwrapThrowable(t);
  179. }
  180. } catch (Throwable t) {
  181. throw new ReflectionException("Could not set property '" + prop.getName() + "' of '" + object.getClass() + "' with value '" + value + "' Cause: " + t.toString(), t);
  182. }
  183. }
  184. @Override
  185. public boolean isCollection() {
  186. return false;
  187. }
  188. @Override
  189. public void add(Object element) {
  190. throw new UnsupportedOperationException();
  191. }
  192. @Override
  193. public <E> void addAll(List<E> list) {
  194. throw new UnsupportedOperationException();
  195. }
  196. }

MapWrapper

  1. public class MapWrapper extends BaseWrapper {
  2. private final Map<String, Object> map;
  3. public MapWrapper(MetaObject metaObject, Map<String, Object> map) {
  4. super(metaObject);
  5. this.map = map;
  6. }
  7. @Override
  8. public Object get(PropertyTokenizer prop) {
  9. // 是否有索引
  10. if (prop.getIndex() != null) {
  11. Object collection = resolveCollection(prop, map);
  12. // 嗲用 BaseWrapper
  13. return getCollectionValue(prop, collection);
  14. } else {
  15. // 获取
  16. return map.get(prop.getName());
  17. }
  18. }
  19. @Override
  20. public void set(PropertyTokenizer prop, Object value) {
  21. if (prop.getIndex() != null) {
  22. Object collection = resolveCollection(prop, map);
  23. setCollectionValue(prop, collection, value);
  24. } else {
  25. map.put(prop.getName(), value);
  26. }
  27. }
  28. @Override
  29. public String findProperty(String name, boolean useCamelCaseMapping) {
  30. return name;
  31. }
  32. @Override
  33. public String[] getGetterNames() {
  34. return map.keySet().toArray(new String[map.keySet().size()]);
  35. }
  36. @Override
  37. public String[] getSetterNames() {
  38. return map.keySet().toArray(new String[map.keySet().size()]);
  39. }
  40. @Override
  41. public Class<?> getSetterType(String name) {
  42. PropertyTokenizer prop = new PropertyTokenizer(name);
  43. if (prop.hasNext()) {
  44. MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
  45. if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
  46. return Object.class;
  47. } else {
  48. return metaValue.getSetterType(prop.getChildren());
  49. }
  50. } else {
  51. if (map.get(name) != null) {
  52. return map.get(name).getClass();
  53. } else {
  54. return Object.class;
  55. }
  56. }
  57. }
  58. @Override
  59. public Class<?> getGetterType(String name) {
  60. PropertyTokenizer prop = new PropertyTokenizer(name);
  61. if (prop.hasNext()) {
  62. MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
  63. if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
  64. return Object.class;
  65. } else {
  66. return metaValue.getGetterType(prop.getChildren());
  67. }
  68. } else {
  69. if (map.get(name) != null) {
  70. return map.get(name).getClass();
  71. } else {
  72. return Object.class;
  73. }
  74. }
  75. }
  76. @Override
  77. public boolean hasSetter(String name) {
  78. return true;
  79. }
  80. @Override
  81. public boolean hasGetter(String name) {
  82. PropertyTokenizer prop = new PropertyTokenizer(name);
  83. if (prop.hasNext()) {
  84. if (map.containsKey(prop.getIndexedName())) {
  85. MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
  86. if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
  87. return true;
  88. } else {
  89. return metaValue.hasGetter(prop.getChildren());
  90. }
  91. } else {
  92. return false;
  93. }
  94. } else {
  95. return map.containsKey(prop.getName());
  96. }
  97. }
  98. @Override
  99. public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
  100. HashMap<String, Object> map = new HashMap<>();
  101. set(prop, map);
  102. return MetaObject.forObject(map, metaObject.getObjectFactory(), metaObject.getObjectWrapperFactory(), metaObject.getReflectorFactory());
  103. }
  104. @Override
  105. public boolean isCollection() {
  106. return false;
  107. }
  108. @Override
  109. public void add(Object element) {
  110. throw new UnsupportedOperationException();
  111. }
  112. @Override
  113. public <E> void addAll(List<E> element) {
  114. throw new UnsupportedOperationException();
  115. }
  116. }

CollectionWrapper

  1. public class CollectionWrapper implements ObjectWrapper {
  2. private final Collection<Object> object;
  3. public CollectionWrapper(MetaObject metaObject, Collection<Object> object) {
  4. this.object = object;
  5. }
  6. @Override
  7. public Object get(PropertyTokenizer prop) {
  8. throw new UnsupportedOperationException();
  9. }
  10. @Override
  11. public void set(PropertyTokenizer prop, Object value) {
  12. throw new UnsupportedOperationException();
  13. }
  14. @Override
  15. public String findProperty(String name, boolean useCamelCaseMapping) {
  16. throw new UnsupportedOperationException();
  17. }
  18. @Override
  19. public String[] getGetterNames() {
  20. throw new UnsupportedOperationException();
  21. }
  22. @Override
  23. public String[] getSetterNames() {
  24. throw new UnsupportedOperationException();
  25. }
  26. @Override
  27. public Class<?> getSetterType(String name) {
  28. throw new UnsupportedOperationException();
  29. }
  30. @Override
  31. public Class<?> getGetterType(String name) {
  32. throw new UnsupportedOperationException();
  33. }
  34. @Override
  35. public boolean hasSetter(String name) {
  36. throw new UnsupportedOperationException();
  37. }
  38. @Override
  39. public boolean hasGetter(String name) {
  40. throw new UnsupportedOperationException();
  41. }
  42. @Override
  43. public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
  44. throw new UnsupportedOperationException();
  45. }
  46. /**
  47. * 是否是list
  48. *
  49. * @return true
  50. */
  51. @Override
  52. public boolean isCollection() {
  53. return true;
  54. }
  55. /**
  56. * java {@link Collection#add(Object)}
  57. *
  58. * @param element
  59. */
  60. @Override
  61. public void add(Object element) {
  62. object.add(element);
  63. }
  64. /**
  65. * java {@link Collection#addAll(Collection)}
  66. *
  67. * @param element
  68. * @param <E>
  69. */
  70. @Override
  71. public <E> void addAll(List<E> element) {
  72. object.addAll(element);
  73. }
  74. }