ObjectFactory
创建对象使用的工厂接口
public interface ObjectFactory {
/**
* Sets configuration properties.
* @param properties configuration properties
*/
default void setProperties(Properties properties) {
// NOP
//No Operation Performed 无操作执行
}
/**
* 使用默认构造方法创建对象
* Creates a new object with default constructor.
* @param type Object type
* @return
*/
T create(Class type);
/**
* 使用特定参数的构造方法创建对象
* Creates a new object with the specified constructor and params.
* @param type Object type
* @param constructorArgTypes Constructor argument types
* @param constructorArgs Constructor argument values
* @return
*/
T create(Class type, List> constructorArgTypes, List
DefaultObjectFactory
默认创建对象的工厂实现,使用 Java 反射技术
public class DefaultObjectFactory implements ObjectFactory, Serializable {
private static final long serialVersionUID = -8855120656740914948L;
@Override
public T create(Class type) {
return create(type, null, null);
}
@SuppressWarnings("unchecked")
@Override
public T create(Class type, List> constructorArgTypes, List
ExampleObjectFactory
对象工厂的样例,样可以在 mybatis-config.xml 对象中指定创建对象的工厂。
public class ExampleObjectFactory extends DefaultObjectFactory {
private Properties properties;
@Override
public T create(Class type) {
return super. create(type);
}
@Override
public T create(Class type, List> constructorArgTypes, List constructorArgs) {
return super. create(type, constructorArgTypes, constructorArgs);
}
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
this.properties = properties;
}
public Properties getProperties() {
return properties;
}
}
Property 工具集
反射模块中使用到的三个属性工具类,分别是 PropertyTokenizer
PropertyNamer 和 PropertyCopier。
PropertyTokenizer
PropertyTokenizer是分词器,编译器,解析这样的 orders[0].items[0].name 表达式,实现了Iterator,具有迭代功能
public class PropertyTokenizer implements Iterator {
// orders[0].items[0].name 第一次迭代
private String name; //当前表达式的名称 orders
private final String indexedName; //当前表达式的索引名 orders[0]
private String index; //索引下标 0
private final String children; //子表达式 items[0].name
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;
}
@Override
public boolean hasNext() {
return children != null;
}
@Override
public PropertyTokenizer next() {
return new PropertyTokenizer(children);
}
@Override
public void remove() {
throw new UnsupportedOperationException("Remove is not supported, as it has no meaning in the context of properties.");
}
}
用例
PropertyTokenizer 继承了 Iterator 接口,它可以法代处理嵌套多层表达式。PropertyTokenizer.next() 方法中会创建新的 PropertyTokenize 对象并解析 children 宇段记录的子表达式。为了便于读者理解,这里继续使用前面的订单示例进行说明,描述解析属性表达式
orders[O].items[O].name 的迭代过程。
PropertyNamer
获取类的 getter、setter 方法 对应的属性名称。
工具类 getter 和 setter 属性的处理方法;
public final class PropertyNamer {
private PropertyNamer() {
// Prevent Instantiation of Static Class
}
//getId -> id;根据get和set方法;返回属性
public static String methodToProperty(String name) {
if (name.startsWith("is")) {
name = name.substring(2);
} else if (name.startsWith("get") || name.startsWith("set")) {
name = name.substring(3);
} else {
throw new ReflectionException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'.");
}
//作用 Id --> id;
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;
}
// 是否是一个类的 getter 和 setter 方法
public static boolean isProperty(String name) {
return isGetter(name) || isSetter(name);
}
//是否包含 get方法 和 is方法
public static boolean isGetter(String name) {
return (name.startsWith("get") && name.length() > 3) || (name.startsWith("is") && name.length() > 2);
}
//是否包含 set方法
public static boolean isSetter(String name) {
return name.startsWith("set") && name.length() > 3;
}
}
PropertyCopier
PropertyCopier 一个属性拷贝的工具类,主要处理相同类型的两个对象之间的属性拷贝。
public final class PropertyCopier {
private PropertyCopier() {
// Prevent Instantiation of Static Class
}
/**
* 主要处理相同类型的两个对象之间的属性拷贝
* @param type
* @param sourceBean 原对象
* @param destinationBean 目标对象
*/
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();
}
}
}
MetaClass
MetaClass 是对 Reflector 的封装,是类层次的信息封装。
MetaClass 通过 Reflector 和 PropertyTokenizer 组合使用, 实现了对复杂的属性表达式的解析,并实现了获取指定属性描述信息的功能。
主要实现了 1.检测是否包含这个复杂的属性表达式,2.属性表达式的返回数据类型 3.返回 Reflector 对象的集合信息们。
public class MetaClass {
//ReflectorFactory 对象,用于缓存 Reflector 对象
private final ReflectorFactory reflectorFactory;
//在创建 MetaClass 时会指定一个类,该 Reflector 对象会用于记录该类相关 的元信息
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);
}
/**
* 根据属性名字,创建这个属性 数据类型的 MetaClass 对象
*/
public MetaClass metaClassForProperty(String name) {
Class> propType = reflector.getGetterType(name);
return MetaClass.forClass(propType, reflectorFactory);
}
/**
* 查找是否有相应的 name(user.address.country) 复杂属性表达式,并返回;只进行了 . 这样复杂属性的导航,并没有对下表进行解析
* @param name
* @return
*/
public String findProperty(String name) {
// 构建的属性信息 user.address.country
StringBuilder prop = buildProperty(name, new StringBuilder());
return prop.length() > 0 ? prop.toString() : null;
}
/**
* 查找是否有相应的 name 属性表达式,并返回
* @param name
* @param useCamelCaseMapping 第二个参数表示是否忽略属性表达式中的下画线
* @return
*/
public String findProperty(String name, boolean useCamelCaseMapping) {
if (useCamelCaseMapping) {
name = name.replace("_", "");
}
return findProperty(name);
}
/**
* 获取类的可读属性们
* @return
*/
public String[] getGetterNames() {
return reflector.getGetablePropertyNames();
}
/**
* 获取类的可写属性们
* @return
*/
public String[] getSetterNames() {
return reflector.getSetablePropertyNames();
}
/**
* 获取属性表达式的数据类型
* @param name
* @return
*/
public Class> getSetterType(String name) {
PropertyTokenizer prop = new PropertyTokenizer(name);
if (prop.hasNext()) {
MetaClass metaProp = metaClassForProperty(prop.getName());
return metaProp.getSetterType(prop.getChildren());
} else {
return reflector.getSetterType(prop.getName());
}
}
/**
* 获取类字段 get 方法的返回值类型
* @param name
* @return
*/
public Class> getGetterType(String name) {
// 新建属性表达式解析器
PropertyTokenizer prop = new PropertyTokenizer(name);
// 是否有孩子节点
if (prop.hasNext()) {
//
MetaClass metaProp = metaClassForProperty(prop);
return metaProp.getGetterType(prop.getChildren());
}
// issue #506. Resolve the type inside a Collection Object
return getGetterType(prop);
}
/**
* 根据包含属性表达式的 PropertyTokenizer 解析器,创建属性的 MetaClass 对象
* @param prop
* @return
*/
private MetaClass metaClassForProperty(PropertyTokenizer prop) {
Class> propType = getGetterType(prop);
return MetaClass.forClass(propType, reflectorFactory);
}
/**
* 根据包含属性的 PropertyTokenizer 对象,返回属性表达式对应的数据类型
* @param prop
* @return
*/
private Class> getGetterType(PropertyTokenizer prop) {
// 返回属性数据类型
Class> type = reflector.getGetterType(prop.getName());
// 该表达式中是否使用 [] 下表,且是 Collection 子类
if (prop.getIndex() != null && Collection.class.isAssignableFrom(type)) {
// 通过 TypeParameterResolver 工具类解析属性的类
Type returnType = getGenericGetterType(prop.getName());
// 针对 ParameterizedType 进行处理,即针对泛型集合类型进行处理
if (returnType instanceof ParameterizedType) {
// 获取实际的参数类型
Type[] actualTypeArguments = ((ParameterizedType) returnType).getActualTypeArguments();
if (actualTypeArguments != null && actualTypeArguments.length == 1) {
// 泛型的类型
returnType = actualTypeArguments[0];
if (returnType instanceof Class) {
type = (Class>) returnType;
} else if (returnType instanceof ParameterizedType) {
type = (Class>) ((ParameterizedType) returnType).getRawType();
}
}
}
}
return type;
}
/**
*
* @param propertyName
* @return
*/
private Type getGenericGetterType(String propertyName) {
try {
// 根据 Reflector.getMethods 集合中记录的 Invoker 实现类的类型,决定解析 getter 方法返回值类型,还是解析字段类型
Invoker invoker = reflector.getGetInvoker(propertyName);
if (invoker instanceof MethodInvoker) {
Field _method = MethodInvoker.class.getDeclaredField("method");
_method.setAccessible(true);
Method method = (Method) _method.get(invoker);
return TypeParameterResolver.resolveReturnType(method, reflector.getType());
} else if (invoker instanceof GetFieldInvoker) {
Field _field = GetFieldInvoker.class.getDeclaredField("field");
_field.setAccessible(true);
Field field = (Field) _field.get(invoker);
return TypeParameterResolver.resolveFieldType(field, reflector.getType());
}
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
return null;
}
/**
* 检查被包装类的属性表达式值是否有Setter()方法
* @param name
* @return
*/
public boolean hasSetter(String name) {
PropertyTokenizer prop = new PropertyTokenizer(name);
if (prop.hasNext()) {
if (reflector.hasSetter(prop.getName())) {
MetaClass metaProp = metaClassForProperty(prop.getName());
return metaProp.hasSetter(prop.getChildren());
} else {
return false;
}
} else {
return reflector.hasSetter(prop.getName());
}
}
/**
* 检查被包装类的属性表达式值是否有 Getter()方法,比如 orders[0].id 属性表达式
* @param name
* @return
*/
public boolean hasGetter(String name) {
// 解析属性表达式
PropertyTokenizer prop = new PropertyTokenizer(name);
if (prop.hasNext()) { // 存在子表达式
if (reflector.hasGetter(prop.getName())) {
// 创建 属性的 MetaClass 对象,递归处理
MetaClass metaProp = metaClassForProperty(prop);
return metaProp.hasGetter(prop.getChildren());
} else {
return false;
}
} else {
return reflector.hasGetter(prop.getName());
}
}
/**
* 获取 get 字段 封装的 Invoker 对象
* @param name
* @return
*/
public Invoker getGetInvoker(String name) {
return reflector.getGetInvoker(name);
}
/**
* 获取 set 字段 封装的 Invoker 对象
* @param name
* @return
*/
public Invoker getSetInvoker(String name) {
return reflector.getSetInvoker(name);
}
/**
* 构建多个属性信息
* 根据属性表达式名称,比如:user.address.country,解析递归,查找在多个类中的多个属性信息,然后拼接属性信息,返回 StringBuilder 对象
* @param name
* @param builder
* @return
*/
private StringBuilder buildProperty(String name, StringBuilder builder) {
PropertyTokenizer prop = new PropertyTokenizer(name);
// 判断 name 属性是否 包含 . ,即是否包含子节点
if (prop.hasNext()) {
// 如果包含子节点,获取父节点的属性名称
String propertyName = reflector.findPropertyName(prop.getName());
if (propertyName != null) {
// 添加到 builder 中
builder.append(propertyName);
builder.append(".");
// 创建这个属性数据类型的的 MetaClass 对象
MetaClass metaProp = metaClassForProperty(propertyName);
// 然后根据父节点的 MetaClass 对象,查找子节点的属性,进行递归查询
metaProp.buildProperty(prop.getChildren(), builder);
}
} else {
// 不包含,然后获取属性名称
String propertyName = reflector.findPropertyName(name);
if (propertyName != null) {
builder.append(propertyName);
}
}
return builder;
}
// 是否有默认的构造方法
public boolean hasDefaultConstructor() {
return reflector.hasDefaultConstructor();
}
}
MetaObject
MetaObject 是对象层级的包装,对象的 getter、setter、filed、和他们的数据类型的方法。
MetaObject 是 Mybatis 提供的一个用于方便、优雅访问对象属性的对象,通过它可以简化代码、不需要 try/catch 各种 reflect 异常,同时它支持对 JavaBean、Collection、Map 三种类型对象的操作。
MetaObject 包装了 objectWrapper,从而提供了对 对象属性 的操作。
反射包的大部分类都是为 MetaObject 服务的,这个是对外暴露的对象原信息操作的接口。
服务类包括:Reflector、ReflectorFactory、MetaClass、ObjectFactory 接口和实现、Invoker 接口和实现、ObjectWrapper 接口和实现、Property 属性工具类。
包装关系:MetaObject -> ObjectWrapper -> MetaClass -> Reflector -> 元类的基础信息(filed、getter、setter 方法、读写属性、成员的数据类型、方法的调用)。
应用场景
- 将对象中的值(parameterType所指定的对象)映射到具体的sql中
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
- 将查询出来的结果填充到具体的对象属性中(由resultMap/resultType指定)
MetaObject
public class MetaObject {
private final Object originalObject; //原始JavaBean对象
private final ObjectWrapper objectWrapper; //其中封装了originalObject对象
private final ObjectFactory objectFactory; //创建对象的工厂
private final ObjectWrapperFactory objectWrapperFactory; //创建封装对象的工厂
private final ReflectorFactory reflectorFactory; //反射工厂
private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
this.originalObject = object;
this.objectFactory = objectFactory;
this.objectWrapperFactory = objectWrapperFactory;
this.reflectorFactory = reflectorFactory;
//赋值给objectWrapper
if (object instanceof ObjectWrapper) {
this.objectWrapper = (ObjectWrapper) object;
} else if (objectWrapperFactory.hasWrapperFor(object)) {
this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);
} else if (object instanceof Map) {
this.objectWrapper = new MapWrapper(this, (Map) object);
} else if (object instanceof Collection) {
this.objectWrapper = new CollectionWrapper(this, (Collection) object);
} else {
this.objectWrapper = new BeanWrapper(this, object);
}
}
public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
if (object == null) {
//系统初始化,默认的对象
return SystemMetaObject.NULL_META_OBJECT;
} else {
return new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
}
}
public ObjectFactory getObjectFactory() {
return objectFactory;
}
public ObjectWrapperFactory getObjectWrapperFactory() {
return objectWrapperFactory;
}
public ReflectorFactory getReflectorFactory() {
return reflectorFactory;
}
public Object getOriginalObject() {
return originalObject;
}
public String findProperty(String propName, boolean useCamelCaseMapping) {
return objectWrapper.findProperty(propName, useCamelCaseMapping);
}
public String[] getGetterNames() {
return objectWrapper.getGetterNames();
}
public String[] getSetterNames() {
return objectWrapper.getSetterNames();
}
public Class> getSetterType(String name) {
return objectWrapper.getSetterType(name);
}
public Class> getGetterType(String name) {
return objectWrapper.getGetterType(name);
}
//判断属性表达式指定属性是 否有 setter 方法
public boolean hasSetter(String name) {
return objectWrapper.hasSetter(name);
}
//判断属性表达式指定属性是 否有 getter 方法
public boolean hasGetter(String name) {
return objectWrapper.hasGetter(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);
}
}
//设置对象属性
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) {
// don't instantiate child path if value is null
return;
} else {
// 为属性表达式指定的属性创建相应的MetaObject对象
metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory);
}
}
metaValue.setValue(prop.getChildren(), value);
} else {
objectWrapper.set(prop, value);
}
}
//根据属性名称获得MetaObject对象
public MetaObject metaObjectForProperty(String name) {
Object value = getValue(name);
return MetaObject.forObject(value, objectFactory, objectWrapperFactory, reflectorFactory);
}
public ObjectWrapper getObjectWrapper() {
return objectWrapper;
}
/**
* 是否是集合
* @return
*/
public boolean isCollection() {
return objectWrapper.isCollection();
}
/**
* 向集合中添加元素
* @param element
*/
public void add(Object element) {
objectWrapper.add(element);
}
/**
* 向集合中添加多个元素
* @param list
* @param
*/
public void addAll(List list) {
objectWrapper.addAll(list);
}
}