一. 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