专栏名称: 失控的阿甘
JAVA
目录
相关文章推荐
IMI财经观察  ·  今日冬至 ·  2 天前  
IMI财经观察  ·  今日冬至 ·  2 天前  
字体设计  ·  三分画七分裱 ·  2 天前  
庞门正道  ·  小姐姐的大跟班。 ·  4 天前  
Duncan艺术菌  ·  Studio Lawahl&瑞典极简美学风向 ·  4 天前  
ZaomeDesign  ·  以人为本!Farrells公布上海北外滩超塔 ... ·  4 天前  
51好读  ›  专栏  ›  失控的阿甘

Mybatis技术内幕(2.3.6):反射模块-Wrapper

失控的阿甘  · 掘金  ·  · 2019-03-28 12:41

正文

阅读 97

Mybatis技术内幕(2.3.6):反射模块-Wrapper

基于Mybatis-3.5.0版本

1.0 Wrapper包

org.apache.ibatis.reflection.wrapper包,如下:

2.0 ObjectWrapper 对象包装器接口

org.apache.ibatis.reflection.property.ObjectWrapper对象包装器接口,基于 MetaClass工具类,定义对指定对象的各种操作。类图和代码如下:

/**
 * 对象包装器接口
 * @author Clinton Begin
 */
public interface ObjectWrapper {

	/**
	 * 根据prop获取对象的属性值 
	 * 1.如果封装的是普通的Bean对象,则调用相应属性的getter方法
	 * 2.如果封装的集合类,则获取指定key或下标对应的value
	 * @param prop PropertyTokenizer分词器对象
	 * @return
	 */
	Object get(PropertyTokenizer prop);

	/**
	 * 根据prop设置对象的属性值
	 * 1.如果封装的是普通的Bean对象,则调用相应属性的setter方法
	 * 2.如果封装的集合类,则设置指定key或下标对应的value
	 * @param prop	PropertyTokenizer分词器对象
	 * @param value 要设置的值
	 */
	void set(PropertyTokenizer prop, Object value);

	/**
	 * 查找属性表达式指定的属性,第二个参数表示是否忽略属性表达式中的下划线
	 * @param name	名称
	 * @param useCamelCaseMapping 是否开启驼峰命名映射
	 * @return
	 */
	String findProperty(String name, boolean useCamelCaseMapping);
	
	/**
	 * 获取对象的可读属性数组
	 * @return
	 */
	String[] getGetterNames();
	
	/**
	 * 获取对象的可写属性数组
	 * @return
	 */
	String[] getSetterNames();
	
	/**
	 * 根据属性表达式获取对应的setter方法的参数类型
	 * @param name
	 * @return
	 */
	Class<?> getSetterType(String name);
	
	/**
	 * 根据属性表达式获取对应的getter方法的返回值类型
	 * @param name
	 * @return
	 */
	Class<?> getGetterType(String name);
	
	/**
	 * 是否有该属性表达式对应的setter方法
	 * @param name
	 * @return
	 */
	boolean hasSetter(String name);
	/**
	 * 是否有该属性表达式对应的getter方法
	 * @param name
	 * @return
	 */
	boolean hasGetter(String name);
	
	/**
	 * 根据属性表达式实例化对象,并set到当前对象
	 * 主要作用于初始化对象属性也是对象的场景
	 * @param name
	 * @param prop
	 * @param objectFactory
	 * @return
	 */
	MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory);

	/**
	 * 是否是集合
	 * @return
	 */
	boolean isCollection();

	/**
	 * 添加元素到集合
	 * @param element
	 */
	void add(Object element);
	
	/**
	 * 批量添加到集合
	 * @param element
	 */
	<E> void addAll(List<E> element);
}
复制代码

2.1 BaseWrapper 基础包装器

org.apache.ibatis.reflection.wrapper.BaseWrapper抽象类,实现ObjectWrapper接口,为子类BeanWrapper和MapWrapper提供公共的方法和属性。代码如下:

/**
 * 抽象类,实现ObjectWrapper接口
 * 为子类BeanWrapper和MapWrapper提供公共的方法和属性
 * @author Clinton Begin
 */
public abstract class BaseWrapper implements ObjectWrapper {
	// 无参数对象,主要用于执行getter方法所需
	protected static final Object[] NO_ARGUMENTS = new Object[0];
	// metaObject对象
	protected final MetaObject metaObject;

	protected BaseWrapper(MetaObject metaObject) {
		this.metaObject = metaObject;
	}

	/**
	 * 处理集合:
	 * 根据PropertyTokenizer获取对应属性的集合(Array、List、Map)对象
	 *
	 * @param prop   PropertyTokenizer 对象
	 * @param object 指定 Object 对象
	 * @return 值
	 */
	protected Object resolveCollection(PropertyTokenizer prop, Object object) {
		if ("".equals(prop.getName())) {
			return object;
		} else {
			return metaObject.getValue(prop.getName());
		}
	}

	/**
	 * 根据PropertyTokenizer获取集合(Array、List、Map)的值
	 * @param prop PropertyTokenizer 对象
	 * @param collection 集合(Array、List、Map)
	 * @return 对应下标或key的值
	 */
	protected Object getCollectionValue(PropertyTokenizer prop, Object collection) {
		if (collection instanceof Map) {
			// 如果是Map类型,则index为key
			return ((Map) collection).get(prop.getIndex());
		} else {
			// 如果是其他集合类型,则index为下标
			int i = Integer.parseInt(prop.getIndex());
			if (collection instanceof List) {
				return ((List) collection).get(i);
			} else if (collection instanceof Object[]) {
				return ((Object[]) collection)[i];
			} else if (collection instanceof char[]) {
				return ((char[]) collection)[i];
			} else if (collection instanceof boolean[]) {
				return ((boolean[]) collection)[i];
			} else if (collection instanceof byte[]) {
				return ((byte[]) collection)[i];
			} else if (collection instanceof double[]) {
				return ((double[]) collection)[i];
			} else if (collection instanceof float[]) {
				return ((float[]) collection)[i];
			} else if (collection instanceof int[]) {
				return ((int[]) collection)[i];
			} else if (collection instanceof long[]) {
				return ((long[]) collection)[i];
			} else if (collection instanceof short[]) {
				return ((short[]) collection)[i];
			} else {
				// 不是集合对象抛ReflectionException异常
				throw new ReflectionException(
						"The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
			}
		}
	}

	/**
	 * 根据PropertyTokenizer设置集合(Array、List、Map)的值
	 * @param prop PropertyTokenizer 对象
	 * @param collection 集合(Array、List、Map)
	 * @param value 值
	 */
	protected void setCollectionValue(PropertyTokenizer prop, Object collection, Object value) {
		if (collection instanceof Map) {
			// 如果是Map类型,则index为key
			((Map) collection).put(prop.getIndex(), value);
		} else {
			// 如果是其他集合类型,则index为下标
			int i = Integer.parseInt(prop.getIndex());
			if (collection instanceof List) {
				((List) collection).set(i, value);
			} else if (collection instanceof Object[]) {
				((Object[]) collection)[i] = value;
			} else if (collection instanceof char[]) {
				((char[]) collection)[i] = (Character) value;
			} else if (collection instanceof boolean[]) {
				((boolean[]) collection)[i] = (Boolean) value;
			} else if (collection instanceof byte[]) {
				((byte[]) collection)[i] = (Byte) value;
			} else if (collection instanceof double[]) {
				((double[]) collection)[i] = (Double) value;
			} else if (collection instanceof float[]) {
				((float[]) collection)[i] = (Float) value;
			} else if (collection instanceof int[]) {
				((int[]) collection)[i] = (Integer) value;
			} else if (collection instanceof long[]) {
				((long[]) collection)[i] = (Long) value;
			} else if (collection instanceof short[]) {
				((short[]) collection)[i] = (Short) value;
			} else {
				// 不是集合对象抛ReflectionException异常
				throw new ReflectionException(
						"The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
			}
		}
	}
}
复制代码

2.2 BeanWrapper 普通对象包装器

org.apache.ibatis.reflection.wrapper.BeanWrapper普通对象包装器,继承BaseWrapper类,基于MetaClass实现对Object的属性操作。代码如下:

/**
 * 继承BaseWrapper,普通Bean包装器。
 * @author Clinton Begin
 */
public class BeanWrapper extends BaseWrapper {
	// 封装的对象
	private final Object object;
	// 封装的对象对应的MetaClass对象
	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) {
		// 存在索引信息,则表示该属性表达式中的name部分为集合类型
		if (prop.getIndex() != null) {
			// 通过BaseWrapper中的公共方法获取集合对象和集合属性
			Object collection = resolveCollection(prop, object);
			return getCollectionValue(prop, collection);
		} else {
			// 不存在索引信息,则name部分为普通对象,查找并调用Invoker相关方法获取属性
			return getBeanProperty(prop, object);
		}
	}

	@Override
	public void set(PropertyTokenizer prop, Object value) {
		// 存在索引信息,则表示该属性表达式中的name部分为集合类型
		if (prop.getIndex() != null) {
			// 通过BaseWrapper中的公共方法获取集合对象,然后设置集合属性
			Object collection = resolveCollection(prop, object);
			setCollectionValue(prop, collection, value);
		} else {
			// 不存在索引信息,则name部分为普通对象,查找并调用Invoker相关方法设置属性
			setBeanProperty(prop, object, value);
		}
	}

	@Override
	public String findProperty(String name, boolean useCamelCaseMapping) {
		return metaClass.findProperty(name, useCamelCaseMapping);
	}

	@Override
	public String[] getGetterNames() {
		return metaClass.getGetterNames();
	}

	@Override
	public String[] getSetterNames() {
		return metaClass.getSetterNames();
	}

	@Override
	public Class<?> getSetterType(String name) {
		// 根据属性表达式创建PropertyTokenizer对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			// 有子表达式,根据indexedName创建MetaObject对象
			MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
			// 对应的属性值为null
			if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
				return metaClass.getSetterType(name);
			} else {
				return metaValue.getSetterType(prop.getChildren());
			}
		} else {
			// 没有子表达式
			return metaClass.getSetterType(name);
		}
	}

	@Override
	public Class<?> getGetterType(String name) {
		// 根据属性表达式创建PropertyTokenizer对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			// 有子表达式,根据indexedName创建MetaObject对象
			MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
			// 对应的属性值为null
			if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
				return metaClass.getGetterType(name);
			} else {
				return metaValue.getGetterType(prop.getChildren());
			}
		} else {
			// 没有子表达式
			return metaClass.getGetterType(name);
		}
	}

	@Override
	public boolean hasSetter(String name) {
		// 根据属性表达式创建PropertyTokenizer对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			if (metaClass.hasSetter(prop.getIndexedName())) {
				// 有子表达式,根据indexedName创建MetaObject对象
				MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
				// 对应的属性值为null
				if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
					return metaClass.hasSetter(name);
				} else {
					return metaValue.hasSetter(prop.getChildren());
				}
			} else {
				return false;
			}
		} else {
			// 没有子表达式
			return metaClass.hasSetter(name);
		}
	}

	@Override
	public boolean hasGetter(String name) {
		// 根据属性表达式创建PropertyTokenizer对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			if (metaClass.hasGetter(prop.getIndexedName())) {
				// 有子表达式,根据indexedName创建MetaObject对象
				MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
				// 对应的属性值为null
				if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
					return metaClass.hasGetter(name);
				} else {
					return metaValue.hasGetter(prop.getChildren());
				}
			} else {
				return false;
			}
		} else {
			// 没有子表达式
			return metaClass.hasGetter(name);
		}
	}

	/**
	 * 主要针对嵌套属性的场景
	 * 即 address.street address.city时
	 * address 也是一个对象,且未初始化
	 * 首次设置address初始化相关对象并赋值到相关属性
	 */
	@Override
	public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
		MetaObject metaValue;
		// 获得 setter 方法的方法参数类型
		Class<?> type = getSetterType(prop.getName());
		try {
			// 创建对象
			Object newObject = objectFactory.create(type);
			// 创建 MetaObject 对象
			metaValue = MetaObject.forObject(newObject, metaObject.getObjectFactory(),
					metaObject.getObjectWrapperFactory(), metaObject.getReflectorFactory());
			// 设置当前对象的值
			set(prop, newObject);
		} catch (Exception e) {
			throw new ReflectionException("Cannot set value of property '" + name + "' because '" + name
					+ "' is null and cannot be instantiated on instance of " + type.getName() + ". Cause:"
					+ e.toString(), e);
		}
		return metaValue;
	}

	/**
	 * 获取Object对应PropertyTokenizer的属性值
	 * @param prop	PropertyTokenizer对象
	 * @param object
	 * @return
	 */
	private Object getBeanProperty(PropertyTokenizer prop, Object object) {
		try {
			// 根据属性名称,查找Reflector.getMethods集合中相应的GetFieldInvoker或MethodInvoker
			Invoker method = metaClass.getGetInvoker(prop.getName());
			try {
				// 获取属性值
				return method.invoke(object, NO_ARGUMENTS);
			} catch (Throwable t) {
				throw ExceptionUtil.unwrapThrowable(t);
			}
		} catch (RuntimeException e) {
			throw e;
		} catch (Throwable t) {
			throw new ReflectionException("Could not get property '" + prop.getName() + "' from " + object.getClass()
					+ ".  Cause: " + t.toString(), t);
		}
	}

	/**
	 * 设置Object对应PropertyTokenizer的属性值
	 * @param prop
	 * @param object
	 * @param value
	 */
	private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) {
		try {
			// 根据属性名称,查找Reflector.setMethods集合中相应的SetFieldInvoker或MethodInvoker
			Invoker method = metaClass.getSetInvoker(prop.getName());
			Object[] params = { value };
			try {
				// 设置属性值
				method.invoke(object, params);
			} catch (Throwable t) {
				throw ExceptionUtil.unwrapThrowable(t);
			}
		} catch (Throwable t) {
			throw new ReflectionException("Could not set property '" + prop.getName() + "' of '" + object.getClass()
					+ "' with value '" + value + "' Cause: " + t.toString(), t);
		}
	}

	@Override
	public boolean isCollection() {
		return false;
	}

	@Override
	public void add(Object element) {
		throw new UnsupportedOperationException();
	}

	@Override
	public <E> void addAll(List<E> list) {
		throw new UnsupportedOperationException();
	}
}
复制代码

2.3 MapWrapper Map对象包装器

org.apache.ibatis.reflection.wrapper.MapWrapperMap对象包装器,继承BaseWrapper类,基于java.util.Map接口方法实现对属性的操作。代码如下:

/**
 * Map 对象包装器
 * @author Clinton Begin
 */
public class MapWrapper extends BaseWrapper {
	// 封装的Map对象
	private final Map<String, Object> map;

	public MapWrapper(MetaObject metaObject, Map<String, Object> map) {
		super(metaObject);
		this.map = map;
	}

	@Override
	public Object get(PropertyTokenizer prop) {
		// 存在索引信息,则表示该属性表达式中的name部分为集合类型
		if (prop.getIndex() != null) {
			// 通过BaseWrapper中的公共方法获取集合对象和集合属性
			Object collection = resolveCollection(prop, map);
			return getCollectionValue(prop, collection);
		} else {
			// 不存在索引信息,则name部分为普通对象,直接从Map中获取值
			return map.get(prop.getName());
		}
	}

	@Override
	public void set(PropertyTokenizer prop, Object value) {
		// 存在索引信息,则表示该属性表达式中的name部分为集合类型
		if (prop.getIndex() != null) {
			// 通过BaseWrapper中的公共方法获取集合对象并设置集合属性
			Object collection = resolveCollection(prop, map);
			setCollectionValue(prop, collection, value);
		} else {
			// 不存在索引信息,则name部分为普通对象,直接Map.put设置值
			map.put(prop.getName(), value);
		}
	}

	@Override
	public String findProperty(String name, boolean useCamelCaseMapping) {
		return name;
	}

	@Override
	public String[] getGetterNames() {
		return map.keySet().toArray(new String[map.keySet().size()]);
	}

	@Override
	public String[] getSetterNames() {
		return map.keySet().toArray(new String[map.keySet().size()]);
	}

	@Override
	public Class<?> getSetterType(String name) {
		// 根据属性表达式创建PropertyTokenizer对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			// 有子表达式,根据indexedName创建MetaObject对象
			MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
			// 对应的属性值为null
			if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
				return Object.class;
			} else {
				// 子表达式由MetaObject处理
				return metaValue.getSetterType(prop.getChildren());
			}
		} else {
			// 没有子表达式
			if (map.get(name) != null) {
				return map.get(name).getClass();
			} else {
				return Object.class;
			}
		}
	}

	@Override
	public Class<?> getGetterType(String name) {
		// 根据属性表达式创建PropertyTokenizer对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			// 有子表达式,根据indexedName创建MetaObject对象
			MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
			// 对应的属性值为null
			if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
				return Object.class;
			} else {
				// 子表达式由MetaObject处理
				return metaValue.getGetterType(prop.getChildren());
			}
		} else {
			// 没有子表达式
			if (map.get(name) != null) {
				return map.get(name).getClass();
			} else {
				return Object.class;
			}
		}
	}

	@Override
	public boolean hasSetter(String name) {
		return true;
	}

	@Override
	public boolean hasGetter(String name) {
		// 根据属性表达式创建PropertyTokenizer对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			if (map.containsKey(prop.getIndexedName())) {
				// 有子表达式,根据indexedName创建MetaObject对象
				MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
				// 对应的属性值为null
				if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
					return true;
				} else {
					// 子表达式由MetaObject处理
					return metaValue.hasGetter(prop.getChildren());
				}
			} else {
				return false;
			}
		} else {
			// 没有子表达式
			return map.containsKey(prop.getName());
		}
	}

	/**
	 * 主要针对嵌套属性的场景
	 * 即 address.street address.city时
	 * 首次设置address会创建一个 key为address value为new HashMap<>()
	 */
	@Override
	public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
		// 创建Map
		HashMap<String, Object> map = new HashMap<>();
		// 设置值
		set(prop, map);
		// 返回封装map的MetaObject对象
		return MetaObject.forObject(map, metaObject.getObjectFactory(), metaObject.getObjectWrapperFactory(),
				metaObject.getReflectorFactory());
	}

	@Override
	public boolean isCollection() {
		return false;
	}

	@Override
	public void add(Object element) {
		throw new UnsupportedOperationException();
	}

	@Override
	public <E> void addAll(List<E> element) {
		throw new UnsupportedOperationException();
	}
}
复制代码

2.4 CollectionWrapper

org.apache.ibatis.reflection.wrapper.CollectionWrapperCollection对象包装器,直接实现ObjectWrapper接口。代码如下:

/**
 * 集合包装器
 * @author Clinton Begin
 */
public class CollectionWrapper implements ObjectWrapper {

	// 封装的集合对象
	private final Collection<Object> object;

	public CollectionWrapper(MetaObject metaObject, Collection<Object> object) {
		this.object = object;
	}

	@Override
	public Object get(PropertyTokenizer prop) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void set(PropertyTokenizer prop, Object value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public String findProperty(String name, boolean useCamelCaseMapping) {
		throw new UnsupportedOperationException();
	}

	@Override
	public String[] getGetterNames() {
		throw new UnsupportedOperationException();
	}

	@Override
	public String[] getSetterNames() {
		throw new UnsupportedOperationException();
	}

	@Override
	public Class<?> getSetterType(String name) {
		throw new UnsupportedOperationException();
	}

	@Override
	public Class<?> getGetterType(String name) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean hasSetter(String name) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean hasGetter(String name) {
		throw new UnsupportedOperationException();
	}

	@Override
	public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean isCollection() {
		return true;
	}

	/**
	 * 添加元素到集合
	 */
	@Override
	public void add(Object element) {
		object.add(element);
	}

	/**
	 * 批量添加元素到集合
	 */
	@Override
	public <E> void addAll(List<E> element) {
		object.addAll(element);
	}
}
复制代码

3.0 ObjectWrapperFactory 对象包装器工厂

org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory对象包装器工厂接口。类图和代码如下:

/**
 * 对象包装器工厂
 * @author Clinton Begin
 */
public interface ObjectWrapperFactory {

	/**
	 * 是否包装了指定对象
	 * @param object 指定对象
	 * @return 是否
	 */
	boolean hasWrapperFor(Object object);

	/**
	 * 获得指定对象的 ObjectWrapper 对象
	 * @param metaObject MetaObject 对象
	 * @param object     指定对象
	 * @return ObjectWrapper 对象
	 */
	ObjectWrapper getWrapperFor(MetaObject metaObject, Object object);
}
复制代码

3.1 DefaultObjectWrapperFactory

org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory实现ObjectWrapperFactory接口。代码如下:

/**
 * @author Clinton Begin
 */
public class DefaultObjectWrapperFactory implements ObjectWrapperFactory {

	@Override
	public boolean hasWrapperFor(Object object) {
		return false;
	}

	@Override
	public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
		throw new ReflectionException(
				"The DefaultObjectWrapperFactory should never be called to provide an ObjectWrapper.");
	}
}
复制代码

3.2 ObjectWrapperFactory扩展点

可以看到DefaultObjectWrapperFactory并未做任何功能性的设计,但是Mybatis提供了基于mybatis-config配置的扩展。配置如下:

<!-- mybatis-config.xml -->
<objectWrapperFactory type="org.apache.ibatis.builder.ExampleObjectWrapperFactory"/>
复制代码

4.0 MetaClass和MetaObject

Wrapper包装器的大部分功能都是委托MetaClass和MetaObject对象实现的,现在来具体看下它们的实现。

4.1 MetaClass 类的元数据

org.apache.ibatis.reflection.MetaClass类的元数据,基于Reflector和PropertyTokenizer组合使用,实现了对复杂的属性表达式的解析。代码如下:

/**
 * 类的元数据
 * 基于Reflector和PropertyTokenizer组合使用,实现了对复杂的属性表达式的解析
 * 
 * @author Clinton Begin
 */
public class MetaClass {
	// Reflector工厂类 默认DefaultReflectorFactory
	private final ReflectorFactory reflectorFactory;
	// 反射器,在创建MetaClass时会指定一个类,该Reflector对象用于记录该类相关的元信息
	private final Reflector reflector;

	private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) {
		this.reflectorFactory = reflectorFactory;
		this.reflector = reflectorFactory.findForClass(type);
	}

	/**
	 * 静态方法创建MetaClass对象
	 * @param type	指定类
	 * @param reflectorFactory	指定ReflectorFactory
	 * @return
	 */
	public static MetaClass forClass(Class<?> type, ReflectorFactory reflectorFactory) {
		return new MetaClass(type, reflectorFactory);
	}

	/**
	 * 创建类的指定属性名的类的 MetaClass对象
	 * @param name
	 * @return
	 */
	public MetaClass metaClassForProperty(String name) {
		Class<?> propType = reflector.getGetterType(name);
		return MetaClass.forClass(propType, reflectorFactory);
	}

	/**
	 * 根据属性表达式获取属性名
	 * @param name
	 * @return
	 */
	public String findProperty(String name) {
		// 委托给buildProperty()方法实现
		StringBuilder prop = buildProperty(name, new StringBuilder());
		return prop.length() > 0 ? prop.toString() : null;
	}

	/**
	 * (重载)根据属性表达式获取属性名
	 * @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();
	}

	/**
	 * 通过表达式 找到对应属性 的setter方法参数类型
	 * @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());
		}
	}

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

	/**
	 * 获取getter类型,如果prop有下标且为集合则获取泛型类型
	 * 例:
	 * private List<String> list;
	 * List<String> getList();
	 * prop list 返回 java.util.List;
	 * prop list[0] 返回 java.lang.String;
	 * @param prop
	 * @return
	 */
	private Class<?> getGetterType(PropertyTokenizer prop) {
		// 获得返回类型
		Class<?> type = reflector.getGetterType(prop.getName());
		// 如果属性表达式有index 且 属性是集合类型
		if (prop.getIndex() != null && Collection.class.isAssignableFrom(type)) {
			// 获取集合的泛型类型
			Type returnType = getGenericGetterType(prop.getName());
			if (returnType instanceof ParameterizedType) {
				Type[] actualTypeArguments = ((ParameterizedType) returnType).getActualTypeArguments();
				// Collection<T>最多只有一个泛型
				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;
	}

	private Type getGenericGetterType(String propertyName) {
		try {
			// 获取属性名对应的Invoker对象
			Invoker invoker = reflector.getGetInvoker(propertyName);
			if (invoker instanceof MethodInvoker) {
				Field _method = MethodInvoker.class.getDeclaredField("method");
				_method.setAccessible(true);
				Method method = (Method) _method.get(invoker);
				// 解析Method获取返回类型
				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);
				// 解析Field获取参数类型
				return TypeParameterResolver.resolveFieldType(field, reflector.getType());
			}
		} catch (NoSuchFieldException | IllegalAccessException ignored) {
		}
		return null;
	}

	public boolean hasSetter(String name) {
		// 解析属性表达式 ,创建PropertyTokenizer对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {// 有子表达式
			// 父级属性名有setter方法
			if (reflector.hasSetter(prop.getName())) {
				// 根据父级属性类型构建MetaClass对象,递归操作
				MetaClass metaProp = metaClassForProperty(prop.getName());
				return metaProp.hasSetter(prop.getChildren());
			} else {
				return false;
			}
		} else {
			return reflector.hasSetter(prop.getName());
		}
	}

	public boolean hasGetter(String name) {
		// 解析属性表达式 ,创建PropertyTokenizer对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {// 有子表达式
			// 父级属性名有getter方法
			if (reflector.hasGetter(prop.getName())) {
				// 根据父级属性类型构建MetaClass对象,递归操作
				MetaClass metaProp = metaClassForProperty(prop);
				return metaProp.hasGetter(prop.getChildren());
			} else {
				return false;
			}
		} else {
			return reflector.hasGetter(prop.getName());
		}
	}

	public Invoker getGetInvoker(String name) {
		return reflector.getGetInvoker(name);
	}

	public Invoker getSetInvoker(String name) {
		return reflector.getSetInvoker(name);
	}

	/**
	 * 
	 * @param name
	 * @param builder
	 * @return
	 */
	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对象
				MetaClass metaProp = metaClassForProperty(propertyName);
				// 递归解析PropertyTokenizer.children字段,并将解析结果添加到builder中保存
				metaProp.buildProperty(prop.getChildren(), builder);
			}
		} else {// 没有子表达式
			// 忽略属性名的大小写
			String propertyName = reflector.findPropertyName(name);
			if (propertyName != null) {
				builder.append(propertyName);
			}
		}
		return builder;
	}

	/**
	 * 判断该类是否有默认无参构造器
	 * @return
	 */
	public boolean hasDefaultConstructor() {
		return reflector.hasDefaultConstructor();
	}
}
复制代码

4.2 MetaObject 对象的元数据

org.apache.ibatis.reflection.MetaObject对象的元数据,Mybatis对象操作的工具类,等同于MetaClass。提供了基于对复杂的属性表达式为对象的属性值的获得和设置等方法。代码如下:

/**
 * 对象元数据
 * Mybatis对象操作的工具类,等同于MetaClass
 * 提供了基于对复杂的属性表达式为对象的属性值的获得和设置等方法。
 * 通过组合的方式(封装ObjectWrapper),对BaseWrapper操作进一步增强。
 * 
 * @author Clinton Begin
 */
public class MetaObject {
	// 原始对象
	private final Object originalObject;
	// 包装过的对象
	private final ObjectWrapper objectWrapper;
	// 对象工厂
	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;

		// 根据object类型,创建对应的Wrapper对象
		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);
		}
	}

	/**
	 * 静态的MetaObject创建方法
	 * @param object
	 * @param objectFactory
	 * @param objectWrapperFactory
	 * @param reflectorFactory
	 * @return
	 */
	public static MetaObject forObject(Object object, ObjectFactory objectFactory,
			ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
		if (object == null) {
			// object为null,创建默认的SystemMetaObject.NULL_META_OBJECT
			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);
	}

	public boolean hasSetter(String name) {
		return objectWrapper.hasSetter(name);
	}

	public boolean hasGetter(String name) {
		return objectWrapper.hasGetter(name);
	}

	public Object getValue(String name) {
		// 根据属性表达式创建PropertyTokenizer对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			// 有子表达式,根据indexedName创建MetaObject对象
			MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
			// 递归判断子表达式 children ,获取值
			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对象
		PropertyTokenizer prop = new PropertyTokenizer(name);
		if (prop.hasNext()) {
			// 有子表达式,根据indexedName创建MetaObject对象
			MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
			// 如果对应的属性值为null
			if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
				if (value == null) {
					// don't instantiate child path if value is null
					return;
				} else {
					// 调用对应的objectWrapper初始化属性值
					metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory);
				}
			}
			// 递归判断子表达式 children ,设置值
			metaValue.setValue(prop.getChildren(), value);
		} else {
			objectWrapper.set(prop, value);
		}
	}

	/**
	 * 根据属性表达式获取属性值,然后创建MetaObject对象
	 * @param name
	 * @return
	 */
	public MetaObject metaObjectForProperty(String name) {
		Object value = getValue(name);
		return MetaObject.forObject(value, objectFactory, objectWrapperFactory, reflectorFactory);
	}

	public ObjectWrapper getObjectWrapper() {
		return objectWrapper;
	}

	public boolean isCollection() {
		return objectWrapper.isCollection();
	}

	public void add(Object element) {
		objectWrapper.add(element);
	}

	public <E> void addAll(List<E> list) {
		objectWrapper.addAll(list);
	}
}
复制代码

4.3 SystemMetaObject

org.apache.ibatis.reflection.SystemMetaObject系统级的MetaObject对象。代码如下:

public final class SystemMetaObject {

	// DefaultObjectFactory 的单例
	public static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
	// DefaultObjectWrapperFactory的单例
	public static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
	// 空对象的 MetaObject 对象单例
	public static final MetaObject NULL_META_OBJECT = MetaObject.forObject(NullObject.class, DEFAULT_OBJECT_FACTORY,
			DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());

	private SystemMetaObject() {
		// Prevent Instantiation of Static Class
	}

	private static class NullObject {}

	/**
	 * 创建 MetaObject 对象
	 *
	 * @param object 指定对象
	 * @return MetaObject 对象
	 */
	public static MetaObject forObject(Object object) {
		return MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY,
				new DefaultReflectorFactory());
	}
}
复制代码

5.0 总结

这一章的内容比较重要,涉及到ORM框架的核心即对象关系映射,简单点讲就是将SQL查询到的数据转换为JavaBean的过程。本章的代码没有很复杂,代码量也是不很大。但是代码的执行轨迹和要实际解决的场景还是比较复杂,需要大家跟着相应的Test类一点一点跟进,去理解不同场景的执行过程。这样才能更好的理解作者的设计思路。

失控的阿甘,乐于分享,记录点滴

推荐文章
IMI财经观察  ·  今日冬至
2 天前
IMI财经观察  ·  今日冬至
2 天前
字体设计  ·  三分画七分裱
2 天前
庞门正道  ·  小姐姐的大跟班。
4 天前
Duncan艺术菌  ·  Studio Lawahl&瑞典极简美学风向
4 天前
北大清华讲座  ·  贝多芬的“命运”变奏曲
7 年前