• 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方法。
  • 相关阅读:
    网络代理技术:保障隐私与增强安全
    Springboot集成kafka高级应用实战
    Protocol Buffers入门
    【小海实习日记】Git使用规范
    awk5个使用场景
    java毕业设计——基于java+J2EE+sqlserver的SMART在线考试系统设计与实现(毕业论文+程序源码)——在线考试系统
    Vue组件(二)父组件、子组件通信/传值
    java计算机毕业设计基于springboot 网上商城购物系统
    四川易点慧电子商务抖音小店打造便捷生活新体验
    C++STL常用算法合集(上)
  • 原文地址:https://blog.csdn.net/Jas000/article/details/126376585