博客
关于我
Mybatis源码分析(四):属性接口之objectFactory
阅读量:298 次
发布时间:2019-03-03

本文共 4597 字,大约阅读时间需要 15 分钟。

点击蓝色字免费订阅,每天收到这样的好信息

一. objectFactory在spring配置文件中的配置

 
   
     

二.源码分析

先看官方文档中ObjectFactory的含义:

MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。 如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。

 

这个对象是mybatis对象实例化用的,本质上内部也是通过构造器来完成的。这个实例对象创建的过程是通过DefaultObjectFactory这类来完成的。但是如果默认的对象工厂无法满足需求,可以定义自己的对象工厂(下面会用实例介绍)。

objectFactory相关配置在源码中加载位置(buildSqlSessionFactory()中):

if (this.objectFactory != null) {      configuration.setObjectFactory(this.objectFactory);}

通过configuration.setObjectFactory(this.objectFactory)可以找到加载过程,configuration数据中心对objectFactory就行了配置,

  protected ObjectFactory objectFactory = new DefaultObjectFactory();

 

DefaultObjectFactory就是我们要找的默认对象工厂(不配置的情况下就会使用配置对象工厂)

DefaultObjectFactory结构:
public class DefaultObjectFactory implements ObjectFactory, Serializable {

这个类实现自接口ObjectFactory。

ObjectFactory接口源码:

public interface ObjectFactory {  /**   * Sets configuration properties.   * @param properties configuration properties   */  void setProperties(Properties properties);  /**   * Creates a new object with default constructor.    * @param type Object type   * @return   */  
T create(Class
type);  /**   * Creates a new object with the specified constructor and params.   * @param type Object type   * @param constructorArgTypes Constructor argument types   * @param constructorArgs Constructor argument values   * @return   */  
T create(Class
type, List
> constructorArgTypes, List
constructorArgs);    /**   * Returns true if this object can have a set of other objects.   * It's main purpose is to support non-java.util.Collection objects like Scala collections.   *   * @param type Object type   * @return whether it is a collection or not   * @since 3.1.0   */  
boolean isCollection(Class
type);}

实现类DefaultObjectFactory源码:

public class DefaultObjectFactory implements ObjectFactory, Serializable {  private static final long serialVersionUID = -8855120656740914948L;  @Override  public 
T create(Class
type) {    return create(type, null, null);  }  @SuppressWarnings("unchecked")  @Override  public
T create(Class
type, List
> constructorArgTypes, List
constructorArgs) {    Class
classToCreate = resolveInterface(type);    // we know types are assignable    return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);  }  @Override  public void setProperties(Properties properties) {    // no props for default  }  
T instantiateClass(Class
type, List
> constructorArgTypes, List
constructorArgs) {       //通过构造器创建的过程,代码太多,省去了,具体可以去DefaultObjectFactory 中看    }  protected Class
resolveInterface(Class
type) {    Class
classToCreate;    if (type == List.class || type == Collection.class || type == Iterable.class) {      classToCreate = ArrayList.class;    } else if (type == Map.class) {      classToCreate = HashMap.class;    } else if (type == SortedSet.class) { // issue #510 Collections Support      classToCreate = TreeSet.class;    } else if (type == Set.class) {      classToCreate = HashSet.class;    } else {      classToCreate = type;    }    return classToCreate;}  @Override  public
boolean isCollection(Class
type) {    return Collection.class.isAssignableFrom(type);  }}

从上面的create方法代码可以看出classToCreate是要创建的类,这个类是通过resolveInterface获取到的,然后通过instantiateClass利用反射机制创建classToCreate的对象,这样就完成了对象实例化过程。

三. 实例扩展

(配置过程参考第一点)

创建对象工厂,必须继承defaultObjectFactory

 

代码实现过程:

/** * @author zhaozhiyong * */public class MyObectFactory extends DefaultObjectFactory {  @Override  public Object create(Class type) {    if (type.equals(User.class)){      User u = (User)super.create(type);      u.setId(1);      u.setName("zhaozhiyong");      u.setAge(1);      return u;    }    return super.create(type);  }  @Override  public void setProperties(Properties properties) {    Iterator iterator = properties.keySet().iterator();    while (iterator.hasNext()){       String keyValue = String.valueOf(iterator.next());       System.out.println(properties.getProperty(keyValue));    }    super.setProperties(properties);  }  @Override  public 
boolean isCollection(Class
type) {    return super.isCollection(type);  }}

单元测试用例代码:

MyObectFactory myObectFactory = new MyObectFactory();User user =(User)myObectFactory.create(User.class);System.out.println("User[id ="+user.getId()+"  name="+user.getName()+"  age="+user.getSex()+"]");//控制台

Test结果:

通过结果可以看出,自定义的对象工厂已经对user实例化了,所以在DefaultObjectFactory无法满足要求的时候,可以自定义对象工厂完成一些特殊的实例化。

转载地址:http://gdzq.baihongyu.com/

你可能感兴趣的文章
焦点事件
查看>>
webpack打包常见报错
查看>>
vuex—1vuex初始
查看>>
axios服务器通信—1axios介绍和使用mock数据
查看>>
web前端面试一从输入url到看到页面发生了什么
查看>>
关于IP地址
查看>>
IO复用之epoll
查看>>
智慧水利的泵站自动化监控系统解决方案
查看>>
C getopt.h
查看>>
TensorRT/parsers/caffe/caffeParser/caffeParser.h源碼研讀
查看>>
PCL MLS論文Computing and Rendering Point Set Surfaces研讀筆記
查看>>
CentOS下Nvidia docker 2.0之安裝教程&踩坑實錄
查看>>
PIL及matplotlib:OSError: cannot identify image file錯誤及解決方式
查看>>
H5页面授权获取微信授权(openId,微信nickname等信息)
查看>>
SpringBoot的URL是如何拼接的
查看>>
2018年年终总结
查看>>
解决checkbox未选中不传递value的多种方法
查看>>
【pgsql-参数详解1】PostgreSQL默认参数值
查看>>
PostgreSQL11-Hash哈希分区数量的设定标准
查看>>
HTTP协议(1)_入门的一些教程和资源
查看>>