Mybatis技術內幕(2.3.6):反射模塊-Wrapper

基於Mybatis-3.5.0版本java

1.0 Wrapper包

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

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提供公共的方法和屬性。代碼以下:mybatis

/** * 抽象類,實現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的屬性操做。代碼以下:app

/** * 繼承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接口。代碼以下:ide

/** * 集合包裝器 * @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接口。代碼以下:ui

/** * @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配置的擴展。配置以下:this

<!-- 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類一點一點跟進,去理解不一樣場景的執行過程。這樣才能更好的理解做者的設計思路。

失控的阿甘,樂於分享,記錄點滴

相關文章
相關標籤/搜索