關於 mybatis 的MetaObject 源碼解讀

# 一.測試代碼:

```
//①通過反射 實例化對象
ObjectFactory objectFactory = new DefaultObjectFactory();
TUser user = objectFactory.create(TUser.class);

ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
③
ReflectorFactory reflectorFactory = new DefaultReflectorFactory();

//②拿到 MeteObject 對象
MetaObject metaObject = MetaObject.forObject(user, objectFactory, objectWrapperFactory, reflectorFactory);

//通過metaObject 可以拿到Reflector,拿到反射對象的各種信息
//使用Reflector讀取類元信息
        Reflector findForClass = reflectorFactory.findForClass(TUser.class);
        Constructor<?> defaultConstructor = findForClass.getDefaultConstructor();
        String[] getablePropertyNames = findForClass.getGetablePropertyNames();
        String[] setablePropertyNames = findForClass.getSetablePropertyNames();
        System.out.println(defaultConstructor.getName());
        System.out.println(Arrays.toString(getablePropertyNames));
        System.out.println(Arrays.toString(setablePropertyNames));
        
//使用metaObject可以獲取ObjectWrapper
//ObjectWrapper讀取對象信息,並對對象屬性進行賦值操作
//        TUser userTemp = new TUser();

        ObjectWrapper wrapperForUser = metaObject.getObjectWrapper();
        wrapperForUser.getGetterNames();
        wrapperForUser.getSetterNames();

        PropertyTokenizer prop = new PropertyTokenizer("userName");
        wrapperForUser.set(prop, " liuyanfei");
        System.out.println(metaObject.getOriginalObject());        
```

# 二.關於①處的源碼  


ObjectFactory:MyBatis每次創建結果對象的新實例時,它都會使用對象工廠(ObjectFactory)去構建POJO;  
ObjectFactory對利用反射創建對象進行了封裝,所以在寫業務代碼的時候可以利用ObjectFactory 的 create 方法快速的創建目標對象。他的實現類是org.apache.ibatis.reflection.factory.DefaultObjectFactory。以下是 DefaultObjectFactory 的部分源碼

```
@Override
  public <T> T create(Class<T> type) {
    return create(type, null, null);
  }

  @SuppressWarnings("unchecked")
  @Override
  public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    Class<?> classToCreate = resolveInterface(type);
    // we know types are assignable
    return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
  }

//調用 create 方法  最終調用的是這個方法
  <T> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
    try {
      Constructor<T> constructor;
      //實力化一個無參的對象
      if (constructorArgTypes == null || constructorArgs == null) {
      //調用 目標類默認的構造器
        constructor = type.getDeclaredConstructor();
        //如果構造器是 private 的,那麼就把他變成 public
        if (!constructor.isAccessible()) {
          constructor.setAccessible(true);
        }
        //調用 jdk 的反射方法 返回實例
        return constructor.newInstance();
      }
      constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
      if (!constructor.isAccessible()) {
        constructor.setAccessible(true);
      }
      return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
    } catch (Exception e) {
      StringBuilder argTypes = new StringBuilder();
      if (constructorArgTypes != null && !constructorArgTypes.isEmpty()) {
        for (Class<?> argType : constructorArgTypes) {
          argTypes.append(argType.getSimpleName());
          argTypes.append(",");
        }
        argTypes.deleteCharAt(argTypes.length() - 1); // remove trailing ,
      }
      StringBuilder argValues = new StringBuilder();
      if (constructorArgs != null && !constructorArgs.isEmpty()) {
        for (Object argValue : constructorArgs) {
          argValues.append(String.valueOf(argValue));
          argValues.append(",");
        }
        argValues.deleteCharAt(argValues.length() - 1); // remove trailing ,
      }
      throw new ReflectionException("Error instantiating " + type + " with invalid types (" + argTypes + ") or values (" + argValues + "). Cause: " + e, e);
    }
  }
```


# 三.②處的源碼。   


### 1.MetaObject中的源碼  


ReflectorFactory:創建Reflector的工廠類,Reflector是mybatis反射模塊的基礎,每個Reflector對象都對應
一個類。ReflectorFactory在其中緩存了Reflector    
ObjectWrapper:對對象的包裝,抽象了對象的屬性信息,他定義了一系列查詢對象屬性信息的方法,以及更
新屬性的 MetaObject 通過靜態方法forObject 實例化 MetaObject

```
private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
    this.originalObject = object;
    this.objectFactory = objectFactory;
    //①
    this.objectWrapperFactory = objectWrapperFactory;
    this.reflectorFactory = reflectorFactory;

    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 {
    //構造函數中會判斷目標類是屬於哪種類型的這裏我們只演示簡單對象,所以最終會執行到這裏  實例化BeanWrapper  
    //BeanWrapper 是ObjectWrapper的實現類。實例化的時候通過構造器把MetaObject對象和目標對象傳進去,接下來看BeanWrapper的實現
      this.objectWrapper = new BeanWrapper(this, object);
    }
  }

  public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
    if (object == null) {
      return SystemMetaObject.NULL_META_OBJECT;
    } else {
      return new MetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
    }
  }
```


### 2.BeanWrapper中的源碼


BaseWrapper:是實現了ObjectWrapper的一個抽象類BeanWrapper中包含兩個屬性,一個是目標對象的實例(object),一個是metaClass

```
public class BeanWrapper extends BaseWrapper {

  private final Object object;
  private final MetaClass metaClass;

  public BeanWrapper(MetaObject metaObject, Object object) {
    super(metaObject);
    this.object = object;
    //實例化BeanWrapper,會調用 MetaClass 的靜態方法forClass
    //注意調用 forClass 會傳入兩個參數,
    //第一個是目標對象的 class,
    //第二個是ReflectorFactory,就是在測試代碼中③處創建的那個 ReflectorFactory,傳遞過程請看 MetaObject的①處
    this.metaClass = MetaClass.forClass(object.getClass(), metaObject.getReflectorFactory());
  }  
  .....
```

### 3.MetaClass 中的源碼


MetaClass 中包含兩個屬性:reflectorFactory、reflector,穩住,已經很接近了

```
public class MetaClass {

  private final ReflectorFactory reflectorFactory;
  private final Reflector reflector;

    //第一個是目標對象的 class,
    //第二個是ReflectorFactory,就是在測試代碼中③處創建的那個 ReflectorFactory
  private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) {
    this.reflectorFactory = reflectorFactory;
    //通過調用reflectorFactory的findForClass獲取到目標類的reflector,基本獲取了 reflector 就已經大功告成了,想幹啥幹啥了,接着再看reflectorFactory如何獲取 reflector
    this.reflector = reflectorFactory.findForClass(type);
  }

  public static MetaClass forClass(Class<?> type, ReflectorFactory reflectorFactory) {
    return new MetaClass(type, reflectorFactory);
  }
  .....
```

### 4.DefaultReflectorFactory中的源碼


ReflectorFactory是一個接口,他的實現類是DefaultReflectorFactory中的源碼
可以看到DefaultReflectorFactory 是把reflectorMap放到 ConcurrentMap 中緩存的,通過findForClass,如果ConcurrentMap中有  目標類 --> Relector  這一組,那麼就返回ConcurrentMap中對應的 relector ,否則就創建 relector。

```
public class DefaultReflectorFactory implements ReflectorFactory {
  private boolean classCacheEnabled = true;
  private final ConcurrentMap<Class<?>, Reflector> reflectorMap = new ConcurrentHashMap<Class<?>, Reflector>();

  public DefaultReflectorFactory() {
  }

  @Override
  public boolean isClassCacheEnabled() {
    return classCacheEnabled;
  }

  @Override
  public void setClassCacheEnabled(boolean classCacheEnabled) {
    this.classCacheEnabled = classCacheEnabled;
  }

  @Override
  public Reflector findForClass(Class<?> type) {
    if (classCacheEnabled) {
            // synchronized (type) removed see issue #461
      Reflector cached = reflectorMap.get(type);
      if (cached == null) {
        cached = new Reflector(type);
        reflectorMap.put(type, cached);
      }
      return cached;
      //上面這一堆  在 mybatis 其他版本的源碼中這樣寫,和上面是一個效果
      //return reflectorMap.computeIfAbsent(type, Reflector::new);
    } else {
      return new Reflector(type);
    }
  }

}
```

關於 Reflector 的解讀可以查看 這篇博客:https://blog.csdn.net/weixin_37139197/article/details/85119383

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章