mybatis基础支持层-反射04:ObjectFactory/Property工具类
一、ObjectFactory
public interface ObjectFactory {
/**
设置参数
*/
void setProperties(Properties properties);
/**
根据class 创建一个无参构造类
*/
<T> T create(Class<T> type);
/**
根据class 创建一个指定参数的类
*/
<T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);
/**
判断是否为Collection集合
*/
<T> boolean isCollection(Class<T> type);
}
DefaultObjectFactory
- Mybatis给出了一个默认的实现
public class DefaultObjectFactory implements ObjectFactory, Serializable {
private static final long serialVersionUID = -8855120656740914948L;
@Override
public <T> T create(Class<T> type) {
//调用create创建一个无参构造类
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);
}
@Override
public void setProperties(Properties properties) {
// no props for default
}
//实例化类的核心方法
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[constructorArgTypes.size()]));
try {
//给出参数数组,构建实例
return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
} catch (IllegalAccessException e) {
if (Reflector.canControlMemberAccessible()) {
constructor.setAccessible(true);
return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
} 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) {
//看type是否是Collection的子类来判断是否是集合
return Collection.class.isAssignableFrom(type);
}
}
- 如需一些定制化的配置,比如类的初始化做一些配置,都可定制化ObjectFactory
二、Property工具集
在反射模块主要用到的三个属性工具类:PropertyTokenizer,PropertyNamer,PropertyCopier
PropertyTokenizer
- 解析item[0].name这些由”.” “[]” 符号组成的表达式
//实现Iterator接口,标识这个类能够迭代使用,可以解析多层[[[].x].xx].xxx的场景
public class PropertyTokenizer implements Iterator<PropertyTokenizer> {
private String name;
private final String indexedName;
private String index;
private final String children;
public PropertyTokenizer(String fullname) {
int delim = fullname.indexOf('.');
//是否包含.
if (delim > -1) {
//包含.
//获取参数的key
name = fullname.substring(0, delim);
//获取参数的value
children = fullname.substring(delim + 1);
} else {
//不包含.
name = fullname;
children = null;
}
indexedName = name;
delim = name.indexOf('[');
//参数的key是否包含[]
if (delim > -1) {
//包含
//索引位置
index = name.substring(delim + 1, name.length() - 1);
//参数真实key
name = name.substring(0, delim);
}
}
PropertyNamer
- 提供静态方法帮助完成方法名到属性名的转换,并作检测
public final class PropertyNamer {
private PropertyNamer() {
// Prevent Instantiation of Static Class
}
public static String methodToProperty(String name) {
//方法为isXXX
if (name.startsWith("is")) {
//去除is,获取属性名称
name = name.substring(2);
} else if (name.startsWith("get") || name.startsWith("set")) {//方法为getXXX setXXX
//去除get set 获取属性名称
name = name.substring(3);
} else {
throw new ReflectionException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'.");
}
//将isXxx getXxx setXxx的驼峰大写改为小写
if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
}
return name;
}
public static boolean isProperty(String name) {
return name.startsWith("get") || name.startsWith("set") || name.startsWith("is");
}
public static boolean isGetter(String name) {
return name.startsWith("get") || name.startsWith("is");
}
public static boolean isSetter(String name) {
return name.startsWith("set");
}
}
PropertyCopier
- 属性拷贝类工具,实现相同类型的对象之间属性的值拷贝
public final class PropertyCopier {
private PropertyCopier() {
// Prevent Instantiation of Static Class
}
public static void copyBeanProperties(Class<?> type, Object sourceBean, Object destinationBean) {
Class<?> parent = type;
while (parent != null) {
//获取类的属性列表
final Field[] fields = parent.getDeclaredFields();
for (Field field : fields) {
try {
try {
//设置目标对象的字段 为源对象对应字段的值
field.set(destinationBean, field.get(sourceBean));
} catch (IllegalAccessException e) {
if (Reflector.canControlMemberAccessible()) {
field.setAccessible(true);
field.set(destinationBean, field.get(sourceBean));
} else {
throw e;
}
}
} catch (Exception e) {
// Nothing useful to do, will only fail on final fields, which will be ignored.
}
}
parent = parent.getSuperclass();
}
}
}