1. 程式人生 > 其它 >mybatis原始碼reflection包--invoker執行器子包

mybatis原始碼reflection包--invoker執行器子包

技術標籤:# mybatis基礎包原始碼java

invoker子包是執行器子包,該包的類能基於反射實現物件方法的呼叫和物件屬性的讀寫。

1.Invoker介面一共三個實現 顧名思義三個實現的作用依次是 物件屬性的寫操作、物件方法的操作、物件屬性的讀操作

2.Invoker介面 兩個方法 (1)獲取型別 (2)執行方法

看一下MethodInvoker實現中Type的含義, 通過分析構造方法, 在method的引數只有一個時 type是入參的型別,否則是方法返回值的型別

public class MethodInvoker implements Invoker {

  // 傳入引數或者傳出引數型別
  private final Class<?> type;
  private final Method method;

  /**
   * MethodInvoker構造方法
   * @param method 方法
   */
  public MethodInvoker(Method method) {
    this.method = method;

    if (method.getParameterTypes().length == 1) {
      // 有且只有一個入參時,這裡放入入參
      type = method.getParameterTypes()[0];
    } else {
      type = method.getReturnType();
    }
  }

  // 執行函式
  @Override
  public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
    try {
      return method.invoke(target, args);
    } catch (IllegalAccessException e) {
      if (Reflector.canControlMemberAccessible()) {
        method.setAccessible(true);
        return method.invoke(target, args);
      } else {
        throw e;
      }
    }
  }

  @Override
  public Class<?> getType() {
    return type;
  }
}
GetFieldInvoker 和 SetFieldInvoker分別通過反射獲取屬性值和設定屬性值
public class SetFieldInvoker implements Invoker {
  // 要操作的屬性
  private final Field field;

  public SetFieldInvoker(Field field) {
    this.field = field;
  }

  @Override
  public Object invoke(Object target, Object[] args) throws IllegalAccessException {
    try {
      // 直接給屬性賦值就可以
      field.set(target, args[0]);
    } catch (IllegalAccessException e) {
      if (Reflector.canControlMemberAccessible()) {
        field.setAccessible(true);
        field.set(target, args[0]);
      } else {
        throw e;
      }
    }
    return null;
  }

  @Override
  public Class<?> getType() {
    return field.getType();
  }
}
public class GetFieldInvoker implements Invoker {
  // 要操作的屬性
  private final Field field;

  public GetFieldInvoker(Field field) {
    this.field = field;
  }

  /**
   * 執行方法
   * @param target 目標物件
   * @param args 方法入參
   * @return 方法的返回結果
   * @throws IllegalAccessException
   */
  @Override
  public Object invoke(Object target, Object[] args) throws IllegalAccessException {
    try {
      // 直接通過反射獲取目標屬性的值
      return field.get(target);
    } catch (IllegalAccessException e) { // 如果無法訪問
      if (Reflector.canControlMemberAccessible()) { // 如果屬性的訪問性可以修改
        // 將屬性的可訪問性修改為可訪問
        field.setAccessible(true);
        // 再次通過反射獲取目標屬性的值
        return field.get(target);
      } else {
        throw e;
      }
    }
  }

  @Override
  public Class<?> getType() {
    return field.getType();
  }
}