一. 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 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 = -8855120656740914948 L; @Override public T create(Class type ) { return create(type , null , null ); } @SuppressWarnings ('unchecked' ) @Override public T create(Class type , List<>?>> constructorArgTypes, ListObject > 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, ListObject > 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.setSex(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无法满足要求的时候,可以自定义对象工厂完成一些特殊的实例化。