MetaObject
是mybatis
中用于处理反射相关的工具类,通过MetaObject
就可以进行获取和设置对象值。
简单使用
简单类型:
1 2 3 4 5 6 7 8 9 10 11
| @Test public void testMetaObject(){ Object blog = new Blog(); Configuration configuration = new Configuration(); MetaObject metaObject = configuration.newMetaObject(blog); metaObject.setValue("id", 1); System.out.println(metaObject.getValue("id")); }
|
复杂类型:
1 2 3 4 5 6 7 8 9
| @Test public void testMetaObject(){ Object blog = new Blog(); Configuration configuration = new Configuration(); MetaObject metaObject = configuration.newMetaObject(blog); metaObject.setValue("author.name", "tommy"); System.out.println(metaObject.getValue("author.name")); }
|
集合类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Test public void testMetaObject(){ Object blog = new Blog(); Configuration configuration = new Configuration(); MetaObject metaObject = configuration.newMetaObject(blog); List<Comment> commentList = new ArrayList<>(5); commentList.add(new Comment()); metaObject.setValue("comments", commentList); metaObject.setValue("comments[0]", new Comment()); System.out.println(metaObject.getValue("comments[0].user.name")); }
|
结构
主要由MetaObject
、ObjectWrapper
、MetaClass
、Reflector
构成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class MetaObject { private final Object originalObject; private final ObjectWrapper objectWrapper; private final ObjectFactory objectFactory; private final ObjectWrapperFactory objectWrapperFactory; 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)) { 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); } }
|
创建完MetaObject
之后,从MetaObject
调用的setValue
、getValue
等属性操作方法实际上都委派给了ObjectWrapper
进行处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public Object getValue(String name) { PropertyTokenizer prop = new PropertyTokenizer(name); if (prop.hasNext()) { MetaObject metaValue = metaObjectForProperty(prop.getIndexedName()); if (metaValue == SystemMetaObject.NULL_META_OBJECT) { return null; } else { return metaValue.getValue(prop.getChildren()); } } else { return objectWrapper.get(prop); } }
|
2.ObjectWrapper
ObjectWrapper
是顶层接口,定义了wrapper
包装原始对象的处理接口,如果原始对象是Bean
对象那么具体的获取属性等操作在BeanWrapper
,如果原始对象是Map
则通过MapWrapper
进行实现具体的属性操作,同理List
则通过CollectionWrapper
进行实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public interface ObjectWrapper {
Object get(PropertyTokenizer prop); void set(PropertyTokenizer prop, Object value); String findProperty(String name, boolean useCamelCaseMapping); String[] getGetterNames(); String[] getSetterNames(); Class<?> getSetterType(String name); Class<?> getGetterType(String name); boolean hasSetter(String name); boolean hasGetter(String name); MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory); boolean isCollection(); void add(Object element); <E> void addAll(List<E> element); }
|
BeanWrapper
和MapWrapper
是继承于抽象类BaseWrapper
,由抽象类继承顶层接口ObjectWrapper
。CollectionWrapper
是直接继承于顶层接口。这是因为如果原始对象是集合,它仅有add
和addAll
操作,其他接口均抛异常。
在BeanWrapper中解析表达式为词法分析器后进行属性操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @Override public void set(PropertyTokenizer prop, Object value) { if (prop.getIndex() != null) { Object collection = resolveCollection(prop, object); setCollectionValue(prop, collection, value); } else { setBeanProperty(prop, object, value); } } private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) { try { Invoker method = metaClass.getSetInvoker(prop.getName()); Object[] params = {value}; try { method.invoke(object, params); } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } } catch (Throwable t) { } }
|
PropertyTokenizer:词法分析器,实现迭代器接口,通过next()
方法解析下一层。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class PropertyTokenizer implements Iterator<PropertyTokenizer> { private String name; private final String indexedName; private String index; private final String children; @Override public boolean hasNext() { return children != null; } @Override public PropertyTokenizer next() { return new PropertyTokenizer(children); } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class MetaClass {
private final ReflectorFactory reflectorFactory; private final Reflector reflector; private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) { this.reflectorFactory = reflectorFactory; this.reflector = reflectorFactory.findForClass(type); } }
|
ReflectorFactory
这个反射工厂的主要作用是对Reflector
反射器进行缓存。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class DefaultReflectorFactory implements ReflectorFactory { private boolean classCacheEnabled = true; private final ConcurrentMap<Class<?>, Reflector> reflectorMap = new ConcurrentHashMap<>();
@Override public Reflector findForClass(Class<?> type) { if (classCacheEnabled) { return reflectorMap.computeIfAbsent(type, Reflector::new); } else { return new Reflector(type); } } }
|
4.Reflector
根据创建的Class
对象,解析出这个类的所有get
、set
方法,构造函数,所有属性字段等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class Reflector {
private final Class<?> type; private final String[] readablePropertyNames; private final String[] writablePropertyNames; private final Map<String, Invoker> setMethods = new HashMap<>(); private final Map<String, Invoker> getMethods = new HashMap<>(); private final Map<String, Class<?>> setTypes = new HashMap<>(); private final Map<String, Class<?>> getTypes = new HashMap<>(); private Constructor<?> defaultConstructor; private Map<String, String> caseInsensitivePropertyMap = new HashMap<>(); public Reflector(Class<?> clazz) { type = clazz; addDefaultConstructor(clazz); addGetMethods(clazz); addSetMethods(clazz); addFields(clazz); readablePropertyNames = getMethods.keySet().toArray(new String[getMethods.keySet().size()]); writablePropertyNames = setMethods.keySet().toArray(new String[setMethods.keySet().size()]); for (String propName : readablePropertyNames) { caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } for (String propName : writablePropertyNames) { caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } } }
|