• Mybatis常用工具类(四)-- ObjectFactory、ProxyFactory


    原文链接:Mybatis常用工具类(四)-- ObjectFactory、ProxyFactory

    ObjectFactory

    每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。 ObjectFactory 的默认实现为 DefaultObjectFactory。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。

    ObjectFactory 方法

    方法 说明
    create(type) 处理无参构造方法
    create(type, constructorArgTypes, constructorArgs) 处理有参构造方法
    setProperties(properties) 设置配置属性
    isCollection(type) 判断是否为集合类型

    ObjectFactory 接口很简单,它包含两个创建实例用的方法,一个是处理默认无参构造方法的,另外一个是处理带参数的构造方法的。

    默认无参构造方法示例:

    ObjectFactory objectFactory = new DefaultObjectFactory();
    Person person = objectFactory.create(Person.class);
    

    带参数的构造方法示例:

    ObjectFactory objectFactory = new DefaultObjectFactory();
    Person person = objectFactory.create(Person.class,
            Arrays.asList(Integer.class, String.class, String.class),
            Arrays.asList(1, "小ben马", "小ben马"));
    

    如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现。eg:

    public class PersonObjectFactory extends DefaultObjectFactory {
        
        // 定义额外属性
        private Properties properties;
    
        @Override
        public Object create(Class type) {
            if (type.equals(Person.class)) {
                Person person = (Person) super.create(type);
                person.setNickName(UUID.randomUUID().toString());
                return person;
            }
            return super.create(type);
        }
    
        @Override
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
    }
    
    <!-- mybatis-config.xml -->
    <objectFactory type="tech.ibit.mybatis.learning.common.tools.factory.PersonObjectFactory">
      <!--设置其他属性-->
      <property name="someProperty" value="100"/>
    </objectFactory>
    

    另外,setProperties 方法可以被用来配置 ObjectFactory,在初始化你的 ObjectFactory 实例后, objectFactory 元素体中定义的属性会被传递给 setProperties 方法。

    ProxyFactory

    ProxyFactory 是 Mybatis 中的代理工厂,主要用于动态代理对象。 ProxyFactory 两个实现,JavassistProxyFactory(支持Javassist动态代理) 和 CglibProxyFactory(支持Cglib动态代理)。ProxyFactory 主要用于 Mybatis 的懒加载功能。当开启懒加载后,Mybatis 创建 Mapper 映射结果对象后,会通过 ProxyFactory 创建映射结果对象的代理对象。当我们调用代理对象的 Getter 方法获取数据时,会执行 JavassistProxyFactory 或 CglibProxyFactory 中定义的拦截逻辑,然后执行一次额外的查询。

    ProxyFactory 主要方法

    方法 说明
    createProxy(target, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs) 创建代理

    示例代码

    JavassistProxyFactory示例

    // 创建ProxyFactory对象
    ProxyFactory proxyFactory = new JavassistProxyFactory();
    Person person = new Person(1, "小ben马", "小ben马");
    ObjectFactory objectFactory = new DefaultObjectFactory();
    
    // 调用ProxyFactory对象的createProxy()方法创建代理对象
    Object proxyOrder = proxyFactory.createProxy(
            person,
            new ResultLoaderMap(),
            new Configuration(),
            objectFactory,
            Arrays.asList(Integer.class, String.class, String.class),
            Arrays.asList(person.getPersonId(), person.getPersonName(), person.getNickName())
    );
    System.out.println(proxyOrder.getClass());
    System.out.println(((Person) proxyOrder).getPersonName());
    

    输出结果>>>

    class tech.ibit.mybatis.learning.common.tools.entity.Person_$$_jvst5_0
    小ben马
    

    CglibProxyFactory示例

    // 创建ProxyFactory对象
    ProxyFactory proxyFactory = new CglibProxyFactory();
    Person person = new Person(1, "小ben马", "小ben马");
    ObjectFactory objectFactory = new DefaultObjectFactory();
    
    // 调用ProxyFactory对象的createProxy()方法创建代理对象
    Object proxyOrder = proxyFactory.createProxy(
            person,
            new ResultLoaderMap(),
            new Configuration(),
            objectFactory,
            Arrays.asList(Integer.class, String.class, String.class),
            Arrays.asList(person.getPersonId(), person.getPersonName(), person.getNickName())
    );
    System.out.println(proxyOrder.getClass());
    System.out.println(((Person) proxyOrder).getPersonName());
    

    需要引入 cglib 相关依赖包。

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.3.0</version>
    </dependency>
    

    输出结果>>>

    class tech.ibit.mybatis.learning.common.tools.entity.Person$$EnhancerByCGLIB$$bfe52ae9
    小ben马
    

    公众号

    喜欢我的文章,请关注公众号

  • 相关阅读:
    两个链表的第一个公共结点
    数组中的逆序对
    第一个只出现一次的字符(字符流中第一个只出现一次的字符)
    丑数
    最长不含有重复字符的子字符串
    礼物的最大价值
    把数字翻译成字符串
    把数组排成最小的数
    [CSP-S模拟测试]:赤(red)(WQS二分+DP)
    [CSP-S模拟测试]:斯诺(snow)(数学+前缀和+树状数组)
  • 原文地址:https://www.cnblogs.com/javaDeveloper/p/13152645.html
Copyright © 2020-2023  润新知