基於Mybatis-3.5.0版本java
org.apache.ibatis.reflection.property
包下主要有三個工具類,以下:apache
org.apache.ibatis.reflection.property.PropertyCopier
屬性複製器,主要用於同一類型兩個對象屬性複製。代碼以下:ide
/** * 屬性複製器 * * @author Clinton Begin */
public final class PropertyCopier {
private PropertyCopier() {
// Prevent Instantiation of Static Class
}
/** * 將 sourceBean 的屬性,複製到 destinationBean 中 * @param type 指定類 * @param sourceBean 來源 Bean 對象 * @param destinationBean 目標 Bean 對象 */
public static void copyBeanProperties(Class<?> type, Object sourceBean, Object destinationBean) {
Class<?> parent = type;
// 循環,從當前類開始,不斷複製到父類,直到父類不存在
while (parent != null) {
// 得到當前 parent 類定義的屬性
final Field[] fields = parent.getDeclaredFields();
for (Field field : fields) {
try {
try {
// 從 sourceBean 中,複製到 destinationBean 去
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();
}
}
}
複製代碼
org.apache.ibatis.reflection.property.PropertyNamer
屬性名工具類,主要用來處理getter和setter方法。代碼以下:工具
/** * 屬性名工具類,主要用來處理getter和setter方法 * @author Clinton Begin */
public final class PropertyNamer {
private PropertyNamer() {
// Prevent Instantiation of Static Class
}
/** * 根據getter或setter方法獲取屬性名 * 規則: * 1.java bean getter/setter 方法命名規範截取屬性名 * 2.根據駝峯命名法 將第一個字符小寫 * @param name * @return */
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'.");
}
/** * 若是截取的屬性名長度爲1或長度大於1且第2位字符是小寫 * 例如: * getA -> A -> a * getAA -> AA -> AA */
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;
}
/** * 判斷是否爲is、get、set方法 * @param name 方法名 * @return */
public static boolean isProperty(String name) {
return name.startsWith("get") || name.startsWith("set") || name.startsWith("is");
}
/** * 判斷是否爲 is、get方法 * @param name 方法名 * @return */
public static boolean isGetter(String name) {
return name.startsWith("get") || name.startsWith("is");
}
/** * 判斷是否爲set方法 * @param name 方法名 * @return */
public static boolean isSetter(String name) {
return name.startsWith("set");
}
}
複製代碼
org.apache.ibatis.reflection.property.PropertyTokenizer
實現Iterator接口,屬性分詞器,支持迭代器的訪問方式。示例和代碼以下:spa
/** * 實現 Iterator 接口,屬性分詞器,支持迭代器的訪問方式 * * @author Clinton Begin */
public class PropertyTokenizer implements Iterator<PropertyTokenizer> {
// 當前表達式的名稱
private String name;
// 當前表達式的索引名
private final String indexedName;
// 索引下標
private String index;
// 子表達式
private final String children;
/** * 對傳入的表達式,並初始化上面的成員變量 * 例: orders[0].item[0].name * name = orders * indexedName = * orders[0] * children = item[0].name * index = 0 * * @param fullname 待解析的表達式 */
public PropertyTokenizer(String fullname) {
// 初始化 name、children 字符串,使用 '.'做爲分隔
int delim = fullname.indexOf('.');
if (delim > -1) {
name = fullname.substring(0, delim);
children = fullname.substring(delim + 1);
} else {
name = fullname;
children = null;
}
indexedName = name;
// 若存在 '[' ,則得到 index ,並修改 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;
}
/** * 迭代方法 建立一個以children爲表達式的PropertyTokenizer對象 */
@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屬性分詞器的實現仍是頗有意思的。你們在實際的開發中若是有相似的業務場景,也能夠考慮這樣設計設計
失控的阿甘,樂於分享,記錄點滴code