抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

MyBatis反射模块分析。

作者:IT王小二
博客:https://itwxe.com

一、orm查询映射过程

反射是 Mybatis 模块中类最多的模块,通过反射实现了 POJO 对象的实例化和 POJO 的属性赋值,往往提到反射,会想到让性能降低,但是,相对 JDK 自带的反射功能,MyBatis 的反射模块功能更为强大,性能更高(当然还是基于jdk反射的封装)。

反射模块关键的几个类如下:

  • ObjectFactory:MyBatis 每次创建结果对象的新实例时,它都会使用对象工厂(ObjectFactory)去构建 POJO 。
  • ReflectorFactory:创建 Reflector 的工厂类,Reflector 是 MyBatis 反射模块的基础,每个 Reflector 对象都对应一个类,在其中缓存了反射操作所需要的类元信息,提高反射性能的秘密就在这里。
  • ObjectWrapperFactory: ObjectWrapper 的工厂类,用于创建 ObjectWrapper 。
  • ObjectWrapper:对对象的包装,抽象了对象的属性信息,定义了一系列查询对象属性信息的方法,以及更新属性的方法。
  • MetaObject:封装了对象元信息,包装了 MyBatis 中五个核心的反射类。也是提供给外部使用的反射工具类,可以利用它可以读取或者修改对象的属性信息。

二、ObjectFactory

MyBatis 每次创建结果对象的新实例时,它都会使用对象工厂(ObjectFactory)去构建 POJO 。

ObjectFactory

public interface ObjectFactory {

/**
* 设置配置信息
*/
default void setProperties(Properties properties) {
// NOP
}

/**
* 通过无参构造函数创建指定类的对象
*/
<T> T create(Class<T> type);

/**
* 根据参数列表,选择合适的构造函数创建对象
*/
<T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);

/**
* 检测指定类型是否为集合类型
*/
<T> boolean isCollection(Class<T> type);

}

ObjectFactory 默认实现类

public class DefaultObjectFactory implements ObjectFactory, Serializable {

private static final long serialVersionUID = -8855120656740914948L;

@Override
public <T> T create(Class<T> type) {
return create(type, null, null);
}

@SuppressWarnings("unchecked")
@Override
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
// 判断类是不是集合类,如果是集合类指定具体的实现类
Class<?> classToCreate = resolveInterface(type);
// we know types are assignable
return (T) instantiateClass(classToCreate, constructorArgTypes, 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();
try {
return constructor.newInstance();
} catch (IllegalAccessException e) {
if (Reflector.canControlMemberAccessible()) {
constructor.setAccessible(true);
return constructor.newInstance();
} else {
throw e;
}
}
}
// 根据指定的参数列表查找构造函数,并实例化对象
constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[0]));
try {
return constructor.newInstance(constructorArgs.toArray(new Object[0]));
} catch (IllegalAccessException e) {
if (Reflector.canControlMemberAccessible()) {
constructor.setAccessible(true);
return constructor.newInstance(constructorArgs.toArray(new Object[0]));
} else {
throw e;
}
}
} catch (Exception e) {
String argTypes = Optional.ofNullable(constructorArgTypes).orElseGet(Collections::emptyList)
.stream().map(Class::getSimpleName).collect(Collectors.joining(","));
String argValues = Optional.ofNullable(constructorArgs).orElseGet(Collections::emptyList)
.stream().map(String::valueOf).collect(Collectors.joining(","));
throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e);
}
}

protected Class<?> resolveInterface(Class<?> type) {
Class<?> classToCreate;
if (type == List.class || type == Collection.class || type == Iterable.class) {
classToCreate = ArrayList.class;
} else if (type == Map.class) {
classToCreate = HashMap.class;
} else if (type == SortedSet.class) { // issue #510 Collections Support
classToCreate = TreeSet.class;
} else if (type == Set.class) {
classToCreate = HashSet.class;
} else {
classToCreate = type;
}
return classToCreate;
}

@Override
public <T> boolean isCollection(Class<T> type) {
return Collection.class.isAssignableFrom(type);
}

}

三、ReflectorFactory

创建 Reflector 的工厂类,Reflector 是 MyBatis 反射模块的基础,每个 Reflector 对象都对应一个类,在其中缓存了反射操作所需要的类元信息,提高反射性能的秘密就在这里。

ReflectorFactory

public interface ReflectorFactory {

boolean isClassCacheEnabled();

void setClassCacheEnabled(boolean classCacheEnabled);

/**
* 通过class创建Reflector
*/
Reflector findForClass(Class<?> type);
}

ReflectorFactory 默认实现类: 在 MyBatis 启动加载时就将xml中需要映射的类元信息加载到 reflectorMap 作为缓存,这就是 MyBatis 提升反射性能的密码所在。

public class DefaultReflectorFactory implements ReflectorFactory {
/**
* class缓存默认开启
*/
private boolean classCacheEnabled = true;
/**
* 使用ConcurrentMap保证线程安全,以class为key,Reflector为value,保存类元信息
*/
private final ConcurrentMap<Class<?>, Reflector> reflectorMap = new ConcurrentHashMap<>();

public DefaultReflectorFactory() {
}

@Override
public boolean isClassCacheEnabled() {
return classCacheEnabled;
}

@Override
public void setClassCacheEnabled(boolean classCacheEnabled) {
this.classCacheEnabled = classCacheEnabled;
}

@Override
public Reflector findForClass(Class<?> type) {
if (classCacheEnabled) {
// synchronized (type) removed see issue #461
return reflectorMap.computeIfAbsent(type, Reflector::new);
} else {
return new Reflector(type);
}
}

}

Reflector:保存类元信息,其中值得注意的是这个类的属性,还有 addFields(Class<?> clazz) 方法,通过 addFields 给这个类添加了get/set方法,哪怕你的pojo不符合规范,没有get/set方法,也给你添加上get/set方法。

public class Reflector {

/**
* 对应的class
*/
private final Class<?> type;
/**
* 可读属性的名称集合,存在get方法即可读
*/
private final String[] readablePropertyNames;
/**
* 可写属性的名称集合,存在set方法即可写
*/
private final String[] writablePropertyNames;
/**
* 保存属性相关的set方法
*/
private final Map<String, Invoker> setMethods = new HashMap<>();
/**
* 保存属性相关的get方法
*/
private final Map<String, Invoker> getMethods = new HashMap<>();
/**
* 保存属性相关的set方法入参类型
*/
private final Map<String, Class<?>> setTypes = new HashMap<>();
/**
* 保存属性相关的get方法返回类型
*/
private final Map<String, Class<?>> getTypes = new HashMap<>();
/**
* class默认的构造函数
*/
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[0]);
writablePropertyNames = setMethods.keySet().toArray(new String[0]);
for (String propName : readablePropertyNames) {
caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
}
for (String propName : writablePropertyNames) {
caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
}
}

/**
* 给这个类添加了get/set方法,哪怕你的pojo不符合规范,没有get/set方法,也给你添加上get/set方法
*/
private void addFields(Class<?> clazz) {
Field[] fields = clazz.getDeclaredFields();
// 遍历class所有的属性
for (Field field : fields) {
// 如果这个属性没有set方法
if (!setMethods.containsKey(field.getName())) {
// issue #379 - removed the check for final because JDK 1.5 allows
// modification of final fields through reflection (JSR-133). (JGB)
// pr #16 - final static can only be set by the classloader
int modifiers = field.getModifiers();
// 如果属性的修饰符不是final和static的,那么就给这个属性生成一个Set方法
if (!(Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers))) {
addSetField(field);
}
}
// 如果这个属性没有Get方法,那个就给它添加一个Get方法
if (!getMethods.containsKey(field.getName())) {
addGetField(field);
}
}
if (clazz.getSuperclass() != null) {
addFields(clazz.getSuperclass());
}
}

private void addSetField(Field field) {
if (isValidPropertyName(field.getName())) {
setMethods.put(field.getName(), new SetFieldInvoker(field));
Type fieldType = TypeParameterResolver.resolveFieldType(field, type);
setTypes.put(field.getName(), typeToClass(fieldType));
}
}

private void addGetField(Field field) {
if (isValidPropertyName(field.getName())) {
getMethods.put(field.getName(), new GetFieldInvoker(field));
Type fieldType = TypeParameterResolver.resolveFieldType(field, type);
getTypes.put(field.getName(), typeToClass(fieldType));
}
}

// 省略其他代码
}

四、ObjectWrapperFactory 和 ObjectWrapper

ObjectWrapperFactory:ObjectWrapper 的工厂类,用于创建 ObjectWrapper 。

public interface ObjectWrapperFactory {

boolean hasWrapperFor(Object object);

ObjectWrapper getWrapperFor(MetaObject metaObject, Object object);

}

ObjectWrapper:对对象的包装,抽象了对象的属性信息,定义了一系列查询对象属性信息的方法,以及更新属性的方法。

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);

}

看到这个一个接口,那么是怎么实现的呢,来看下它的实现类。

  • public abstract class BaseWrapper implements ObjectWrapper
  • public class BeanWrapper extends BaseWrapper

看下 BeanWrapper 这个类,可以看到这里实现了get/set方法的具体实现,其中有个 metaClass 是什么呢,这个其实就是包装了 ReflectorReflectorFactory

public class BeanWrapper extends BaseWrapper {

/**
* 实例对象
*/
private final Object object;
/**
* 元信息
*/
private final MetaClass metaClass;

public BeanWrapper(MetaObject metaObject, Object object) {
super(metaObject);
this.object = object;
this.metaClass = MetaClass.forClass(object.getClass(), metaObject.getReflectorFactory());
}

@Override
public Object get(PropertyTokenizer prop) {
if (prop.getIndex() != null) {
// 如果是集合属性
Object collection = resolveCollection(prop, object);
return getCollectionValue(prop, collection);
} else {
// 如果不是集合属性
return getBeanProperty(prop, object);
}
}

@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);
}
}

// 省略其他代码
}
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);
}

public static MetaClass forClass(Class<?> type, ReflectorFactory reflectorFactory) {
return new MetaClass(type, reflectorFactory);
}

// 省略其他代码
}

五、MetaObject

封装了对象元信息,包装了 MyBatis 中五个核心的反射类。也是提供给外部使用的反射工具类,可以利用它可以读取或者修改对象的属性信息。

public class MetaObject {

/**
* 原始的Java对象
*/
private final Object originalObject;
private final ObjectWrapper objectWrapper;
private final ObjectFactory objectFactory;
private final ObjectWrapperFactory objectWrapperFactory;
private final ReflectorFactory reflectorFactory;

// 省略其他代码
}

都读到这里了,来个 点赞、评论、关注、收藏 吧!

评论



Copyright Author Powered Theme

ICP