mybatis原始碼reflection包--屬性子包
阿新 • • 發佈:2021-01-09
技術標籤:# mybatis基礎包原始碼
reflection包下的property包是屬性子包,該包中的類用來完成物件屬性相關的操作。
1.該包下一共三個類
(1)PropertyCopier 提供物件屬性複製功能。 以下程式碼是PropertyCopier物件copy的方法,通過反射獲取需要copy型別的所有欄位然後把源對像的值放到目標物件中,如果源物件有父類就繼續複製父類的屬性值
/** * 完成物件的輸出拷貝 * @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(); } }
(2)PropertyNamer 屬性(包括屬性方法)名稱處理器
methodToProperty的作用 例如 getName 把Name截取出來 然後把N小寫 最後返回name
public final class PropertyNamer { private PropertyNamer() { // Prevent Instantiation of Static Class } // 將方法名轉化為屬性名 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'."); } // 將方法名中屬性的大小寫修改正確 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); } public static boolean isGetter(String name) { return (name.startsWith("get") && name.length() > 3) || (name.startsWith("is") && name.length() > 2); } public static boolean isSetter(String name) { return name.startsWith("set") && name.length() > 3; } }
(3)PropertyTokenizer 屬性標記器
* 假設傳入的為student[sId].name * 則各個屬性得到以下結果 * * 該屬性標記器只能處理一級,即點後面的都作為children
public class PropertyTokenizer implements Iterator<PropertyTokenizer> { // student private String name; // student[sId] private final String indexedName; // sId private String index; // name private final String children; 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); } }