Mybatis的MetaObject解析

SqlSessionFactory初始化:[url]http://donald-draper.iteye.com/2331917[/url]
Mybatis加载解析Mapper(xml)文件第一讲:[url]http://donald-draper.iteye.com/blog/2333125[/url]
Mybatis加载解析Mapper(xml)文件第二讲:[url]http://donald-draper.iteye.com/blog/2333191[/url]
Mybatis 解析Mapper(class):[url]http://donald-draper.iteye.com/blog/2333293[/url]
Mybatis的Environment解析详解:[url]http://donald-draper.iteye.com/blog/2334133[/url]
mybatis 动态标签语句的解析(BoundSql):[url]http://donald-draper.iteye.com/blog/2334135[/url]

在我们前面几篇文章中,经常出现一个类为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;
}

总结:
[color=blue]从上面可以看出,MetaObject是用于包装Object的,将Object包装成ObjectWrapper,MapWrapper,CollectionWrapper,BeanWrapper等,ObjectWrapper是对应属性及方法的一个包装类,MetaObject获取obejct的属性值,以及给属性设置,是委托给
ObjectWrapper,ObjectWrapper在委托给MetaClass,MetaClass最后交Reflector;Reflector包含Obejct的属性名,set方法,以及get方法的描述,MetaObject获取属性值和设置属性值方法,本质上是,从Reflector获取属性对应方法的Invoker,然后invoke。下面一节,我们讲Reflector。[/color]


//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();
}

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值