MetaObject简介
MetaObject对象是Mybatis框架用于访问对象属性的工作类,底层实现为java的反射基础。目前只支持JavaBean、Collection、Map三种类型对象访问,也可以自定义其他类型
Bean访问例子
public class BeanTest {
public static void main(String[] args) {
Person person = new Person();
MetaObject metaObject = SystemMetaObject.forObject(person);
metaObject.setValue("id", 34567);
metaObject.setValue("name", "aaa");
System.out.println(metaObject.getValue("id"));
System.out.println(metaObject.getValue("name"));
}
static class Person {
int id;
String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
测试结果
34567
aaa
Collection访问例子
public class CollectionTest {
public static void main(String[] args) {
Person person = new Person();
person.getList().add("aaaa");
person.getList().add("bbbb");
person.getList().add("cccc");
MetaObject metaObject = SystemMetaObject.forObject(person);
System.out.println(metaObject.getValue("list[1]"));
}
static class Person {
List<String> list = new ArrayList<>();
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}
}
测试结果
bbbb
Map访问例子
public class MapTest {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("name", "zhangsan");
MetaObject metaObject = SystemMetaObject.forObject(map);
System.out.println(metaObject.getValue("name"));
}
}
测试结果
zhangsan
MetaObject结构
MetaObject对象主要由于下来对象组成
- Object原对象:持有原始对象
- ObjectFactory对象工厂:负责创建对象,对象可能层层嵌套,都对象为null时,需要通过对象工厂创建
- ObjectWrapper包装对象:增强原始对象功能
- ObjectWrapperFactory包装对象工厂
- ReflectorFactory反射器工厂:Class元信息的封装
接下来,我们将分三部分来讲解
- 反射器类 :【深入理解MyBatis】- 07Mybatis 反射器Reflector源码
- 对象包装类
- 对象工厂
默认对象工厂类DefaultObjectFactory,逻辑也比较简单
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
// 做接口转换,将接口绑定上默认实现类,如Map->HashMap等
Class<?> classToCreate = resolveInterface(type);
// 实例化类classToCreate
return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
}
核心方法instantiateClass,对应获取构造器为constructor = type .getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
/**
* type: 对象class
* constructorArgTypes: 参数class列表
* constructorArgs: 参数值列表
*/
private <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
try {
Constructor<T> constructor;
if (constructorArgTypes == null || constructorArgs == null) {
constructor = type.getDeclaredConstructor();
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
return constructor.newInstance();
}
constructor = type
.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
if (!constructor.isAccessible()) {
constructor.setAccessible(true);
}
return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
} catch (Exception e) {
StringBuilder argTypes = new StringBuilder();
if (constructorArgTypes != null && !constructorArgTypes.isEmpty()) {
for (Class<?> argType : constructorArgTypes) {
argTypes.append(argType.getSimpleName());
argTypes.append(",");
}
argTypes.deleteCharAt(argTypes.length() - 1); // remove trailing ,
}
StringBuilder argValues = new StringBuilder();
if (constructorArgs != null && !constructorArgs.isEmpty()) {
for (Object argValue : constructorArgs) {
argValues.append(String.valueOf(argValue));
argValues.append(",");
}
argValues.deleteCharAt(argValues.length() - 1); // remove trailing ,
}
throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes
+ ") or values (" + argValues + "). Cause: " + e, e);
}
}