1. 程式人生 > 其它 >mybatis原始碼reflection包--屬性子包

mybatis原始碼reflection包--屬性子包

技術標籤:# 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);
    }
  }