Mybatis加载解析Mapper(xml)文件第一讲: http://donald-draper.iteye.com/blog/2333125
Mybatis加载解析Mapper(xml)文件第二讲: http://donald-draper.iteye.com/blog/2333191
Mybatis 解析Mapper(class): http://donald-draper.iteye.com/blog/2333293
Mybatis的Environment解析详解: http://donald-draper.iteye.com/blog/2334133
mybatis 动态标签语句的解析(BoundSql): http://donald-draper.iteye.com/blog/2334135
在我们前面几篇文章中,经常出现一个类为MetaObject,今天我们就来看看,MetaObject的作用在讲Environments解析的时候有这么一段代码,设置数据源的属性
public void setProperties(Properties properties) { Properties driverProperties = new Properties(); //获取dataSource的对象描述 MetaObject metaDataSource = SystemMetaObject.forObject(dataSource); //获取dataSource的所有属性,并设置 for(Iterator i$ = properties.keySet().iterator(); i$.hasNext();) { Object key = i$.next(); String propertyName = (String)key; if(propertyName.startsWith("driver.")) { String value = properties.getProperty(propertyName); driverProperties.setProperty(propertyName.substring(DRIVER_PROPERTY_PREFIX_LENGTH), value); } else if(metaDataSource.hasSetter(propertyName)) { String value = (String)properties.get(propertyName); Object convertedValue = convertValue(metaDataSource, propertyName, value); metaDataSource.setValue(propertyName, convertedValue); } } //设置metaDataSource的driverProperties属性 if(driverProperties.size() > 0) metaDataSource.setValue("driverProperties", driverProperties); }
我们可以看到有这么几句代码
MetaObject metaDataSource = SystemMetaObject.forObject(dataSource); metaDataSource.hasSetter(propertyName) metaDataSource.setValue("driverProperties", driverProperties);
来看一下SystemMetaObject
public class SystemMetaObject { public static final ObjectFactory DEFAULT_OBJECT_FACTORY; public static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY; public static final MetaObject NULL_META_OBJECT; private static class NullObject { private NullObject() { } } public static MetaObject forObject(Object object) { return MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY); } static { DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory(); DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory(); NULL_META_OBJECT = MetaObject.forObject(org/apache/ibatis/reflection/SystemMetaObject$NullObject, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY); } }
从上面的SystemMetaObject,我们可以看出,SystemMetaObject返回对象的MetaObject对象,实际上通过的MetaObject的forObject方法。
//Sql包装类
public class BoundSql { public BoundSql(Configuration configuration, String sql, List parameterMappings, Object parameterObject) { this.sql = sql; this.parameterMappings = parameterMappings; this.parameterObject = parameterObject; additionalParameters = new HashMap(); metaParameters = configuration.newMetaObject(additionalParameters); } private String sql; private List parameterMappings; private Object parameterObject; private Map additionalParameters; private MetaObject metaParameters; }
在Sql包装类,我们可以看到一下几句代码:
metaParameters = configuration.newMetaObject(additionalParameters); //Configuration新建MetaObject对象 public MetaObject newMetaObject(Object object) { return MetaObject.forObject(object, objectFactory, objectWrapperFactory); }
下面来看MetaObject
//MetaObject,设置Class实例属性
public class MetaObject { private Object originalObject;//原始Obeject private ObjectWrapper objectWrapper;//包装后的Object private ObjectFactory objectFactory; private ObjectWrapperFactory objectWrapperFactory; private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) { originalObject = object; this.objectFactory = objectFactory; this.objectWrapperFactory = objectWrapperFactory; if(object instanceof ObjectWrapper) objectWrapper = (ObjectWrapper)object; else //如果对应objectWrapperFactory中存在,则返回object if(objectWrapperFactory.hasWrapperFor(object)) objectWrapper = objectWrapperFactory.getWrapperFor(this, object); else if(object instanceof Map) //Map objectWrapper = new MapWrapper(this, (Map)object); else if(object instanceof Collection) //List objectWrapper = new CollectionWrapper(this, (Collection)object); else //bean objectWrapper = new BeanWrapper(this, object); } //构造MetaObject public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) { if(object == null) return SystemMetaObject.NULL_META_OBJECT; else return new MetaObject(object, objectFactory, objectWrapperFactory); } public String findProperty(String propName, boolean useCamelCaseMapping) { return objectWrapper.findProperty(propName, useCamelCaseMapping); } //获取可读属性名 public String[] getGetterNames() { return objectWrapper.getGetterNames(); } //获取可写属性名 public String[] getSetterNames() { return objectWrapper.getSetterNames(); } //获取对象属性name对应的值 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); } } //给对象属性name设置value值 public void setValue(String name, Object value) { PropertyTokenizer prop = new PropertyTokenizer(name); if(prop.hasNext()) { MetaObject metaValue = metaObjectForProperty(prop.getIndexedName()); if(metaValue == SystemMetaObject.NULL_META_OBJECT) { if(value == null && prop.getChildren() != null) return; metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory); } metaValue.setValue(prop.getChildren(), value); } else { objectWrapper.set(prop, value); } } }
下面我们先来看forObject方法
private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) { originalObject = object; this.objectFactory = objectFactory; this.objectWrapperFactory = objectWrapperFactory; if(object instanceof ObjectWrapper) objectWrapper = (ObjectWrapper)object; else //如果对应objectWrapperFactory中存在,则返回object if(objectWrapperFactory.hasWrapperFor(object)) objectWrapper = objectWrapperFactory.getWrapperFor(this, object); else if(object instanceof Map) //Map objectWrapper = new MapWrapper(this, (Map)object); else if(object instanceof Collection) //List objectWrapper = new CollectionWrapper(this, (Collection)object); else //bean objectWrapper = new BeanWrapper(this, object); } //构造MetaObject public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) { if(object == null) return SystemMetaObject.NULL_META_OBJECT; else return new MetaObject(object, objectFactory, objectWrapperFactory); } //DefaultObjectWrapperFactory public class DefaultObjectWrapperFactory implements ObjectWrapperFactory { public boolean hasWrapperFor(Object object) { return false; } public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) { throw new RuntimeException("The DefaultObjectWrapperFactory should never be called to provide an ObjectWrapper."); } }
从MetaObject的forObject方法,我们可以看出,实际上,MetaObject的构造函数
MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory)是把原始Obejct包装成ObjectWrapper(ObjectWrapper,MapWrapper,CollectionWrapper,BeanWrapper),
如果ObjectWrapperFactory已经包装了Object,则通过ObjectWrapperFactory的 getWrapperFor(MetaObject metaObject, Object object)返回相应的ObjectWrapper。
在来看获取属性值方法,这里我们来看BeanWrapper
public String findProperty(String propName, boolean useCamelCaseMapping) { return objectWrapper.findProperty(propName, useCamelCaseMapping); }
//BeanWrapper
public class BeanWrapper extends BaseWrapper { private Object object; private MetaClass metaClass;//Object对应的Class public BeanWrapper(MetaObject metaObject, Object object) { super(metaObject); this.object = object; metaClass = MetaClass.forClass(object.getClass()); } //获取属性name对应的属性名 public String findProperty(String name, boolean useCamelCaseMapping) { return metaClass.findProperty(name, useCamelCaseMapping); } }
//MetaClass
public class MetaClass { private Reflector reflector; public static MetaClass forClass(Class type) { return new MetaClass(type); } private MetaClass(Class type) { //获取type类型对应的Reflector reflector = Reflector.forClass(type); } //获取name对应的属性名,useCamelCaseMapping是否是驼峰命名 public String findProperty(String name, boolean useCamelCaseMapping) { if(useCamelCaseMapping) name = name.replace("_", ""); return findProperty(name); } public String findProperty(String name) { StringBuilder prop = buildProperty(name, new StringBuilder()); return prop.length() <= 0 ? null : prop.toString(); } private StringBuilder buildProperty(String name, StringBuilder builder) { PropertyTokenizer prop = new PropertyTokenizer(name); if(prop.hasNext()) { String propertyName = reflector.findPropertyName(prop.getName()); if(propertyName != null) { builder.append(propertyName); builder.append("."); MetaClass metaProp = metaClassForProperty(propertyName); metaProp.buildProperty(prop.getChildren(), builder); } } else { String propertyName = reflector.findPropertyName(name); if(propertyName != null) builder.append(propertyName); } return builder; } }
//Reflector
public class Reflector { private static boolean classCacheEnabled = true; private static final String EMPTY_STRING_ARRAY[] = new String[0]; private static final Map REFLECTOR_MAP = new ConcurrentHashMap(); private Class type; private String readablePropertyNames[]; private String writeablePropertyNames[]; private Map setMethods; private Map getMethods; private Map setTypes; private Map getTypes; private Constructor defaultConstructor; private Map caseInsensitivePropertyMap; //构造Class对应的Reflector public static Reflector forClass(Class clazz) { if(classCacheEnabled) { //如果缓存状态开启,则从REFLECTOR_MAP获取对应的Reflector,没有则重新构建 Reflector cached = (Reflector)REFLECTOR_MAP.get(clazz); if(cached == null) { cached = new Reflector(clazz); REFLECTOR_MAP.put(clazz, cached); } return cached; } else { return new Reflector(clazz); } } private Reflector(Class clazz) { readablePropertyNames = EMPTY_STRING_ARRAY;//可读属性名 writeablePropertyNames = EMPTY_STRING_ARRAY;//可写属性名 setMethods = new HashMap();//Set方法Map getMethods = new HashMap();//Get方法Map setTypes = new HashMap(); getTypes = new HashMap(); caseInsensitivePropertyMap = new HashMap();//大小写不敏感属性Map type = clazz; addDefaultConstructor(clazz); addGetMethods(clazz); addSetMethods(clazz); addFields(clazz); readablePropertyNames = (String[])getMethods.keySet().toArray(new String[getMethods.keySet().size()]); writeablePropertyNames = (String[])setMethods.keySet().toArray(new String[setMethods.keySet().size()]); //将可读属性添加大小写不敏感属性Map String arr$[] = readablePropertyNames; int len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String propName = arr$[i$]; caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } //将可写属性添加大小写不敏感属性Map arr$ = writeablePropertyNames; len$ = arr$.length; for(int i$ = 0; i$ < len$; i$++) { String propName = arr$[i$]; caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName); } } public String findPropertyName(String name) { return (String)caseInsensitivePropertyMap.get(name.toUpperCase(Locale.ENGLISH)); } }
回到MetaObject,再看获取属性get与setName的属性
public String[] getGetterNames() { return objectWrapper.getGetterNames(); } public String[] getSetterNames() { return objectWrapper.getSetterNames(); }
再看BeanWrapper的相应方法,并委托给MetaClass对应方法
//BeanWrapper
public String[] getGetterNames() { return metaClass.getGetterNames(); } public String[] getSetterNames() { return metaClass.getSetterNames(); }
// MetaClass对应方法委托给Reflector
public String[] getGetterNames() { return reflector.getGetablePropertyNames(); } public String[] getSetterNames() { return reflector.getSetablePropertyNames(); }
再看Reflector
public String[] getGetablePropertyNames() { return readablePropertyNames; } public String[] getSetablePropertyNames() { return writeablePropertyNames; }
实际上返回的是可读与可写属性名字符串组;
回到MetaObject,再看获取对象属性name对应的值
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); } }
//BeanWrapper
public Object get(PropertyTokenizer prop) { if(prop.getIndex() != null) { Object collection = resolveCollection(prop, object); return getCollectionValue(prop, collection); } else { //获取bean对应的属性 return getBeanProperty(prop, object); } }
通过MetaClass获取属性对应的get方法,调用相应的方法
private Object getBeanProperty(PropertyTokenizer prop, Object object) { Invoker method = metaClass.getGetInvoker(prop.getName()); return method.invoke(object, NO_ARGUMENTS); throw ExceptionUtil.unwrapThrowable(t); throw new ReflectionException((new StringBuilder()).append("Could not get property '").append(prop.getName()).append("' from ").append(object.getClass()).append(". Cause: ").append(t.toString()).toString(), t); }
//BaseWrapper
protected Object getCollectionValue(PropertyTokenizer prop, Object collection) { if(collection instanceof Map) return ((Map)collection).get(prop.getIndex()); int i = Integer.parseInt(prop.getIndex()); if(collection instanceof List) return ((List)collection).get(i); if(collection instanceof Object[]) return ((Object[])(Object[])collection)[i]; if(collection instanceof char[]) return Character.valueOf(((char[])(char[])collection)[i]); if(collection instanceof boolean[]) return Boolean.valueOf(((boolean[])(boolean[])collection)[i]); if(collection instanceof byte[]) return Byte.valueOf(((byte[])(byte[])collection)[i]); if(collection instanceof double[]) return Double.valueOf(((double[])(double[])collection)[i]); if(collection instanceof float[]) return Float.valueOf(((float[])(float[])collection)[i]); if(collection instanceof int[]) return Integer.valueOf(((int[])(int[])collection)[i]); if(collection instanceof long[]) return Long.valueOf(((long[])(long[])collection)[i]); if(collection instanceof short[]) return Short.valueOf(((short[])(short[])collection)[i]); else throw new ReflectionException((new StringBuilder()).append("The '").append(prop.getName()).append("' property of ").append(collection).append(" is not a List or Array.").toString()); }
// MetaClass的获取属性的Get方法,委托给Reflector
public Invoker getGetInvoker(String name) { return reflector.getGetInvoker(name); }
再看Reflector
从get方法Map中,获取对应的Invoker
public Invoker getGetInvoker(String propertyName) { Invoker method = (Invoker)getMethods.get(propertyName); if(method == null) throw new ReflectionException((new StringBuilder()).append("There is no getter for property named '").append(propertyName).append("' in '").append(type).append("'").toString()); else return method; }
回到MetaObject,再看给对象属性name设置value值
public void setValue(String name, Object value) { PropertyTokenizer prop = new PropertyTokenizer(name); if(prop.hasNext()) { MetaObject metaValue = metaObjectForProperty(prop.getIndexedName()); if(metaValue == SystemMetaObject.NULL_META_OBJECT) { if(value == null && prop.getChildren() != null) return; metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory); } metaValue.setValue(prop.getChildren(), value); } else { objectWrapper.set(prop, value); } }
//BeanWrapper
public void set(PropertyTokenizer prop, Object value) { if(prop.getIndex() != null) { Object collection = resolveCollection(prop, object); setCollectionValue(prop, collection, value); } else { //设置bean属性 setBeanProperty(prop, object, value); } }
//获取bean属性对应的set方法,并设置
private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) { try { Invoker method = metaClass.getSetInvoker(prop.getName()); Object params[] = { value }; try { method.invoke(object, params); } } }
// MetaClass,获取set方法,委托给Reflector
public Invoker getSetInvoker(String name) { return reflector.getSetInvoker(name); } 再看Reflector,从setMethods方法Map中,获取Invoker public Invoker getSetInvoker(String propertyName) { Invoker method = (Invoker)setMethods.get(propertyName); if(method == null) throw new ReflectionException((new StringBuilder()).append("There is no setter for property named '").append(propertyName).append("' in '").append(type).append("'").toString()); else return method; }
总结:
从上面可以看出,MetaObject是用于包装Object的,将Object包装成ObjectWrapper,MapWrapper,CollectionWrapper,BeanWrapper等,ObjectWrapper是对应属性及方法的一个包装类,MetaObject获取obejct的属性值,以及给属性设置,是委托给
ObjectWrapper,ObjectWrapper在委托给MetaClass,MetaClass最后交Reflector;Reflector包含Obejct的属性名,set方法,以及get方法的描述,MetaObject获取属性值和设置属性值方法,本质上是,从Reflector获取属性对应方法的Invoker,然后invoke。下面一节,我们讲Reflector。
//PropertyTokenizer
public class PropertyTokenizer implements Iterable, Iterator { private String name; private String indexedName; private String index; private String children; public PropertyTokenizer(String fullname) { int delim = fullname.indexOf('.'); if(delim > -1) { name = fullname.substring(0, delim); children = fullname.substring(delim + 1); } else { name = fullname; children = null; } indexedName = name; delim = name.indexOf('['); if(delim > -1) { index = name.substring(delim + 1, name.length() - 1); name = name.substring(0, delim); } } public String getName() { return name; } public String getIndex() { return index; } public String getIndexedName() { return indexedName; } public String getChildren() { return children; } public boolean hasNext() { return children != null; } public PropertyTokenizer next() { return new PropertyTokenizer(children); } public void remove() { throw new UnsupportedOperationException("Remove is not supported, as it has no meaning in the context of properties."); } public Iterator iterator() { return this; } public volatile Object next() { return next(); } }