mybatis+mybatisplus源码学习(十三)MetaObject

本文详细介绍了Mybatis中的MetaObject,用于反射解析对象信息。内容涵盖MetaObject的使用,如对象、集合和Map类型的属性操作,以及MetaObject的内部实现原理,包括SystemMetaObject、MetaObject构建、属性获取与设置等核心方法的解析。通过示例代码展示了如何利用MetaObject进行对象属性的动态操作。
摘要由CSDN通过智能技术生成


前言

Mybatis中提供了MetaObject,用来将一个对象的信息通过反射解析出来,保存了对象的元数据,可以通过ognl表达式设置和获取属性。


一、MetaObject的使用

(1)Object类型

可以对对象设置属性值和获取属性值。包括嵌套的属性

	@Test
    public void testObject() {
        Student student = new Student(1L, "stu1", new Address("中国", "北京"));
        MetaObject metaObject = SystemMetaObject.forObject(student);
        Object name = metaObject.getValue("name");//获取属性值
        System.out.println(name);
        metaObject.setValue("name", "stu2");//设置属性值
        name = metaObject.getValue("name");
        System.out.println(name);
        Object country = metaObject.getValue("address.country");//是哦那个ognl获取值
        System.out.println(country);
    }

(2)Collection类型
可以对集合添加元素,不能获取元素,获取方法会抛异常

 	@Test
    public void testCollection() {
        Student student1 = new Student(1L, "stu1", new Address("中国", "北京"));
        Student student2 = new Student(2L, "stu2", new Address("中国", "上海"));
        List<Student> students = new ArrayList<>();
        students.add(student1);
        MetaObject metaObject = SystemMetaObject.forObject(students);
        metaObject.add(student2);//添加元素
        System.out.println(students.size());
    }

(3)Map类型

可以对map类型添加元素和获取元素

	@Test
    public void testMap() {
        Student student1 = new Student(1L, "stu1", new Address("中国", "北京"));
        Student student2 = new Student(2L, "stu2", new Address("中国", "上海"));
        Map map = new HashMap();
        map.put("student1", student1);
        MetaObject metaObject = SystemMetaObject.forObject(map);
        metaObject.setValue("student2", student2);//put
        System.out.println(map.size());
        System.out.println(metaObject.getValue("student2.name"));//get
    }

二、MetaObject的原理

1、SystemMetaObject

public final class SystemMetaObject {
  //默认对象工厂
  public static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
  //默认对象包装器工厂
  public static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
  //空对象的MetaObject 
  public static final MetaObject NULL_META_OBJECT = MetaObject.forObject(NullObject.class, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());

  private SystemMetaObject() {
    // Prevent Instantiation of Static Class
  }

  private static class NullObject {
  }

  public static MetaObject forObject(Object object) {
    return MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
  }

  }

2、MetaObject的构建

(1)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) {
   	 //Map
      this.objectWrapper = new MapWrapper(this, (Map) object);
    } else if (object instanceof Collection) {
      //Collection
      this.objectWrapper = new CollectionWrapper(this, (Collection) object);
    } else {
      //Bean
      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)MapWrapper

 public MapWrapper(MetaObject metaObject, Map<String, Object> map) {
    super(metaObject);
    //保存传入的map
    this.map = map;
  }

(3)CollectionWrapper

public CollectionWrapper(MetaObject metaObject, Collection<Object> object) {
    //保存传入的Collection
    this.object = object;
  }

(4)BeanWrapper

public BeanWrapper(MetaObject metaObject, Object object) {
    super(metaObject);
    this.object = object;
    this.metaClass = MetaClass.forClass(object.getClass(), metaObject.getReflectorFactory());
  }

forClass( )方法

public static MetaClass forClass(Class<?> type, ReflectorFactory reflectorFactory) {
    return new MetaClass(type, reflectorFactory);
  }
private MetaClass(Class<?> type, ReflectorFactory reflectorFactory) {
    this.reflectorFactory = reflectorFactory;
    this.reflector = reflectorFactory.findForClass(type);
  }

DefaultReflectorFactory的findForClass( )方法

public Reflector findForClass(Class<?> type) {
    if (classCacheEnabled) {
      // synchronized (type) removed see issue #461
      //缓存对象的反射信息
      return reflectorMap.computeIfAbsent(type, Reflector::new);
    } else {
      return new Reflector(type);
    }
  }

创建了一个Reflector对象

public Reflector(Class<?> clazz) {
	//类型
    type = clazz;
    //默认构造方法
    addDefaultConstructor(clazz);
    //属性的get方法
    addGetMethods(clazz);
    //属性的set方法
    addSetMethods(clazz);
    //字段信息
    addFields(clazz);
    readablePropertyNames = getMethods.keySet().toArray(new String[0]);
    writablePropertyNames = setMethods.keySet().toArray(new String[0]);
    for (String propName : readablePropertyNames) {
      caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
    }
    for (String propName : writablePropertyNames) {
      caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
    }
  }

3、MetaObject获取值

(1)getValue( )

public Object getValue(String name) {
	//按照 . 拆分
    PropertyTokenizer prop = new PropertyTokenizer(name);
    if (prop.hasNext()) {
      //按照属性的层级递归获取子属性
      MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
      if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
        return null;
      } else {
      	//获取子属性的值
        return metaValue.getValue(prop.getChildren());
      }
    } else {
      //获取最后一层属性的值
      return objectWrapper.get(prop);
    }
  }

metaObjectForProperty

 public MetaObject metaObjectForProperty(String name) {
    //深度遍历获取子属性的值
    Object value = getValue(name);
    //为子属性创建MetaObject
    return MetaObject.forObject(value, objectFactory, objectWrapperFactory, reflectorFactory);
  }

(2)MapWrapper

public Object get(PropertyTokenizer prop) {
    if (prop.getIndex() != null) {
      //还有下一层级,继续解析
      Object collection = resolveCollection(prop, map);
      return getCollectionValue(prop, collection);
    } else {
      //从map中获取值
      return map.get(prop.getName());
    }
  }
 protected Object resolveCollection(PropertyTokenizer prop, Object object) {
    if ("".equals(prop.getName())) {
      return object;
    } else {
      //解析map的子属性
      return metaObject.getValue(prop.getName());
    }
  }
protected Object getCollectionValue(PropertyTokenizer prop, Object collection) {
    if (collection instanceof Map) {
      //map
      return ((Map) collection).get(prop.getIndex());
    } else {
      //数组或集合根据下表获取对应的元素
      int i = Integer.parseInt(prop.getIndex());
      if (collection instanceof List) {
        return ((List) collection).get(i);
      } else if (collection instanceof Object[]) {
        return ((Object[]) collection)[i];
      } else if (collection instanceof char[]) {
        return ((char[]) collection)[i];
      } else if (collection instanceof boolean[]) {
        return ((boolean[]) collection)[i];
      } else if (collection instanceof byte[]) {
        return ((byte[]) collection)[i];
      } else if (collection instanceof double[]) {
        return ((double[]) collection)[i];
      } else if (collection instanceof float[]) {
        return ((float[]) collection)[i];
      } else if (collection instanceof int[]) {
        return ((int[]) collection)[i];
      } else if (collection instanceof long[]) {
        return ((long[]) collection)[i];
      } else if (collection instanceof short[]) {
        return ((short[]) collection)[i];
      } else {
        throw new ReflectionException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
      }
    }

(3)CollectionWrapper

get方法会抛异常

  public Object get(PropertyTokenizer prop) {
    throw new UnsupportedOperationException();
  }

(4)BeanWrapper

public Object get(PropertyTokenizer prop) {
    if (prop.getIndex() != null) {
      //如果属性是集合
      Object collection = resolveCollection(prop, object);
      return getCollectionValue(prop, collection);
    } else {
      //获取bean的属性值
      return getBeanProperty(prop, object);
    }
  }
 private Object getBeanProperty(PropertyTokenizer prop, Object object) {
    try {
      //找到属性的get方法
      Invoker method = metaClass.getGetInvoker(prop.getName());
      try {
      	//反射调用
        return method.invoke(object, NO_ARGUMENTS);
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    } catch (RuntimeException e) {
      throw e;
    } catch (Throwable t) {
      throw new ReflectionException("Could not get property '" + prop.getName() + "' from " + object.getClass() + ".  Cause: " + t.toString(), t);
    }
  }
 public Invoker getGetInvoker(String name) {
 	//通过reflector获取方法
    return reflector.getGetInvoker(name);
  }
public Invoker getGetInvoker(String propertyName) {
	//根据属性名从缓存的方法中获取到
    Invoker method = getMethods.get(propertyName);
    if (method == null) {
      throw new ReflectionException("There is no getter for property named '" + propertyName + "' in '" + type + "'");
    }
    return method;
  }

4、MetaObject设置值

(1)MetaObject

 public void setValue(String name, Object value) {
    PropertyTokenizer prop = new PropertyTokenizer(name);
    if (prop.hasNext()) {
      MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
      if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
        if (value == null) {
          // don't instantiate child path if value is null
          return;
        } else {
          //对子属性进行初始化
          metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory);
        }
      }
      //对子属性设置值
      metaValue.setValue(prop.getChildren(), value);
    } else {
      //对最后一层属性设置值
      objectWrapper.set(prop, value);
    }
  }

(2)MapWrapper

初始化

public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
	//创建了一个Hashmap
    HashMap<String, Object> map = new HashMap<>();
    set(prop, map);
    return MetaObject.forObject(map, metaObject.getObjectFactory(), metaObject.getObjectWrapperFactory(), metaObject.getReflectorFactory());
  }

设置值

  public void set(PropertyTokenizer prop, Object value) {
    if (prop.getIndex() != null) {
     //操作map中的元素
      Object collection = resolveCollection(prop, map);
      setCollectionValue(prop, collection, value);
    } else {
     //操作map
      map.put(prop.getName(), value);
    }
  }

(3)CollectionWrapper

初始化和设置值都抛异常

  @Override
  public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
    throw new UnsupportedOperationException();
  }
  @Override
  public void set(PropertyTokenizer prop, Object value) {
    throw new UnsupportedOperationException();
  }

(4)BeanWrapper

初始化

@Override
  public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
    MetaObject metaValue;
    Class<?> type = getSetterType(prop.getName());
    try {
      //使用DefaultObjectFactory初始化对象
      Object newObject = objectFactory.create(type);
      metaValue = MetaObject.forObject(newObject, metaObject.getObjectFactory(), metaObject.getObjectWrapperFactory(), metaObject.getReflectorFactory());
      //设置对象属性
      set(prop, newObject);
    } catch (Exception e) {
      throw new ReflectionException("Cannot set value of property '" + name + "' because '" + name + "' is null and cannot be instantiated on instance of " + type.getName() + ". Cause:" + e.toString(), e);
    }
    return metaValue;
  }

设置值

 @Override
  public void set(PropertyTokenizer prop, Object value) {
    if (prop.getIndex() != null) {
      //对集合、map、数组属性设置值
      Object collection = resolveCollection(prop, object);
      setCollectionValue(prop, collection, value);
    } else {
      //对bean属性设置值,反射
      setBeanProperty(prop, object, value);
    }
  }

总结

本文主要介绍了MetaObject的使用及原理。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_lrs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值