Mybatis源码分析(五):属性接口之objectFactory

版权声明:欢迎转载,注明出处即可,谢谢! https://blog.csdn.net/qq_17231297/article/details/84567222

一. 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结果:
在这里插入图片描述
通过结果可以看出,自定义的对象工厂已经对user实例化了,所以在DefaultObjectFactory无法满足要求的时候,可以自定义对象工厂完成一些特殊的实例化。
欢迎大家加入Java高级架构/互联网(严禁培训机构、广告群,最干净的技术交流群):微信号:1083683150(备注:技术群或者4000G架构师资源)

微信平台本人收集个大量资源(4000G架构师资源,1000G大数据资源),只做分享,欢迎大家关注获取,保证免费,非任何机构

更多精彩请扫码关注微信公众号—— 名称:java版web项目 id :java_project
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_17231297/article/details/84567222