Configuration--objectFactory(三-3)

上一篇文章我们分析了标签typeAliases的解析,这篇文章我们接着分析下一个标签objectFactory的解析.

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

我们可以在Configuration中看出,默认的对象工厂为:

protected ObjectFactory objectFactory = new DefaultObjectFactory();

我们也可以定义自己的对象工厂,如:

<objectFactory type="org.mybatis.example.ExampleObjectFactory">
  <property name="someProperty" value="100"/>
</objectFactory>

那接下来让我们看看代码中是怎么解析这个标签的,我们来看objectFactoryElement(root.evalNode(“objectFactory”));方法:

  private void objectFactoryElement(XNode context) throws Exception {
    if (context != null) {
      // 获取objectFactory标签中的type属性值
      String type = context.getStringAttribute("type");
      // 获取objectFactory标签下所有子标签的name,value封装成Properties
      Properties properties = context.getChildrenAsProperties();
      // 实例化ObjectFactory工厂类,resolveClass方法是定义在BaseBuilder中,下面再进一步分析
      ObjectFactory factory = (ObjectFactory) resolveClass(type).newInstance();
      // 设置工厂参数
      factory.setProperties(properties);
      // 将自定义的objectFactory设置进Configuration中,从这里我们可以看出,我们自己实现的实例工厂类要实现ObjectFactory接口
      configuration.setObjectFactory(factory);
    }
  }

分析(ObjectFactory) resolveClass(type).newInstance()方法:

  // 该方法返回一个Class对象,newInstance()调用构造方法实例化对象.
  protected Class<?> resolveClass(String alias) {
    if (alias == null) return null;
    try {
      return resolveAlias(alias);
    } catch (Exception e) {
      throw new BuilderException("Error resolving class. Cause: " + e, e);
    }
  }

  protected Class<?> resolveAlias(String alias) {
    // typeAliasRegistry是不是似曾相识,这个属性就是存放别名的,所以可以看出,我们可以给自己的实例化工厂取别名,通过别名的方法去寻找它,那有的同学肯定也有疑惑,那我如果没有定义别名呢?我们接着看typeAliasRegistry的resolveAlias方法.
    return typeAliasRegistry.resolveAlias(alias);
  }

继续看typeAliasRegistry.resolveAlias(alias)方法:

  // 上一篇文章中,我们说了别名的注册,其实这个方法,就是通过别名去获取Class类对象.还记得当时我们最终存储别名的时候,别名存储为小写吗?现在我们来验证一下,取值的时候是不是也是要转换成小写,再去取值.
  public <T> Class<T> resolveAlias(String string) {
    try {
      if (string == null) return null;
      // 果然,一开始就直接就别名转换成小写
      String key = string.toLowerCase(Locale.ENGLISH);
      Class<T> value;
      if (TYPE_ALIASES.containsKey(key)) {
        // 如果有相应的别名存储,则返回别名对应的Class值
        value = (Class<T>) TYPE_ALIASES.get(key);
      } else {
        // 如果没有相应的别名存储,则通过Resources去加载这个类
        value = (Class<T>) Resources.classForName(string);
      }
      return value;
    } catch (ClassNotFoundException e) {
      throw new TypeException("Could not resolve type alias '" + string + "'.  Cause: " + e, e);
    }
  }

当我们要自定义实例化工厂时,实现的ObjectFactory接口也很简单,它包含两个创建用的方法.一个是处理默认构造方法的,另外一个是处理带参数的构造方法的. 最后,setProperties方法可以被用来配置ObjectFactor.在初始化你的ObjectFactory实例后,objectFactory元素体中定义的属性会被传递给setProperties方法,我们也在上述代码中看到了factory.setProperties(properties);.

至此,objectFactory就介绍完啦.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值