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

 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
   <property name="objectFactory" ref="objectFactory"/>
    
</bean>
<!--额外定义对象工厂-->
<bean id="objectFactory" 
class="com.zzy.mybatisex.objectfactory.MyObectFactory">
       <!-- 一些属性 -->
</bean>

 

二.源码分析

 

先看官方文档中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> T create(Class<T> 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> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> 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
   */
  <T> boolean isCollection(Class<T> type);

}

 

 

实现类DefaultObjectFactory源码:

 

public class DefaultObjectFactory implements ObjectFactory, Serializable {

  private static final long serialVersionUID = -8855120656740914948L;

  @Override
  public <T> T create(Class<T> type) {
    return create(type, null, null);
  }

  @SuppressWarnings("unchecked")
  @Override
  public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> 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> T instantiateClass(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> 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 <T> boolean isCollection(Class<T> 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 <T> boolean isCollection(Class<T> 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结果:

 

Mybatis源码分析(四):属性接口之objectFactory_加载

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