Mybatis源码分析(四):属性接口之objectFactory
发布日期:2021-05-06 22:20:11 浏览次数:10 分类:技术文章

本文共 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无法满足要求的时候,可以自定义对象工厂完成一些特殊的实例化。

上一篇:java socket异常总结
下一篇:Java进阶知识点6:并发容器背后的设计理念 - 锁分段

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年03月21日 20时25分16秒