• Mybatis工具—反射工具(MetaObject)


      MetaObject是Mybatis中的反射工具类,其位于Mybatis源码包中的org.apache.ibatis.reflection。从MetaObject的命名和所处的位置不难看出,该类主要的工作就是获取和设置对象的属性值。

    @Data
    public class Robot{
        private String name;
    }
        
    Robot robot = new Robot();
    // 使用SystemMetaObject类的静态方法forObject()构造MetaObject
    MetaObject metaObject = SystemMetaObject.forObject(robot);
    metaObject.setValue("name", "机器人0001");
    Object value = metaObject.getValue("name");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

      从上述示例代码可以看出,MetaObject类是使用SystemMetaObject类的静态方法forObject()来完成构造的,那么为什么要使用SystemMetaObject类的静态方法forObject()来构造呐?这里就不得不从MetaObject类的构造方法说起了。

    构造方法

      MetaObject构造方法的源代码如下:

    /**
     * @param object               原始对象
     * @param objectFactory        对象工厂
     * @param objectWrapperFactory 对象包装工厂
     * @param reflectorFactory     反射工厂
     */ 
    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 {
          this.objectWrapper = new BeanWrapper(this, object);
        }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

      从源代码可以看出MetaObject类的构造方法被改为了private私有域,这也是不能直接通过new MetaObject()来构造MetaObject对象的主要原因。通过观察MetaObject构造方法可以看出,如果想要构造一个MetaObject对象就除了提供想要操作的原始object以外,同时还要提供ObjectFactory、ObjectWrapperFactory和ReflectorFactory三个同样位于org.apache.ibatis.reflection包下的反射操作接口。

    • ObjectFactory

      ObjectFactory位于Mybatis源代码org.apache.ibatis.reflection.factory包中,从所处的包和命名不难看出,该接口的主要职责就是用来创建所需类的对象。其主要实现类DefaultObjectFactory实现了所需的所有方法。

    • ObjectWrapperFactory

      ObjectWrapperFactory位于Mybaits源代码org.apache.ibatis.reflection.wrapper包中,该接口主要的职责就是将某个对象包装成ObjectWrapper对象,其主要实现类DefaultObjectWrapperFactory提供了支持。

    • ReflectorFactory

      ReflectorFactory位于Mybatis源代码org.apache.ibatis.reflection包中,该接口的主要职责就是对目标对象进行反射操作提供能力,其主要实现类DefaultReflectorFactory提供了支持。
    从MetaObject构造方法的源代码来看,其除了对Object object、ObjectFactory objectFactory、ObjectWrapperFactory objectWrapperFactory和ReflectorFactory reflectorFactory这个属性进行赋值以外,还通过判断目标对象object的对象属性来构造ObjectWrapper对象来作为整个反射操作后的承载。在构造ObjectWrapper对象的过程中,同时使用到了之前已经赋值好的objectFactory、objectWrapperFactory和reflectorFactory对象。

    SystemMetaObject

      至此再来看下SystemMetaObject类中的静态方法forObject构造MetaObject对象的细节,SystemMetaObject源代码中定义了两个常量分别对应ObjectFactory和ObjectWrapperFactor,最终这两个常量会用于调用MetaObject.forObject()方法来构造MetaObject对象。
      从SystemMetaObject类中的静态方法forObject得出,最终还是调用了MetaObject.forObject()方法来构造MetaObject对象

    public final class SystemMetaObject {
    
      public static final ObjectFactory DEFAULT_OBJECT_FACTORY = 
                  new DefaultObjectFactory();
      public static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = 
                  new DefaultObjectWrapperFactory();
      public static final MetaObject NULL_META_OBJECT = MetaObject.forObject(
                  new NullObject(), 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());
      }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    MetaObject操作对象

      上述已经明白了MetaObject对象是如何构造而来的,并且从构造方法我们不难看出MetaObject类使用了组合模式,配合originalObject、objectWrapper、objectFactory、objectWrapperFactory和reflectorFactory五个属性对象来使得原始对象完成反射操作。

    1. Object getValue(String name),获取目标对象中某个属性对应的值。
    2. void setValue(String name, Object value),将值value赋值到目标对象的name属性中。
    3. boolean hasSetter(String name),判断目标对象name属相是否有setter方法。
    4. boolean hasGetter(String name),判断目标对象name属相是否有getter方法。
  • 相关阅读:
    RibbonControl
    java计算机毕业设计web考试资料交易系统设计与实现源码+mysql数据库+系统+lw文档+部署
    经典算法系列之(一):算法的基础概念,数据结构的基础概念,以及算法+数据结构=程序
    泛微E9,独立选择框对应数据库表查询
    springboot缓存
    PyTorch入门之【CNN】
    Flask框架——基于类的视图
    刚爆火就下线的 ZAO 换脸,背后是另一场技术人的狂欢
    AOP 笔记
    Aigtek高精度电流源仪器设计规范
  • 原文地址:https://blog.csdn.net/Jas000/article/details/126376585