ObjectFactory
每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。 ObjectFactory 的默认实现为 DefaultObjectFactory。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。
ObjectFactory 方法
方法 | 说明 |
---|---|
create(type) | 处理无参构造方法 |
create(type, constructorArgTypes, constructorArgs) | 处理有参构造方法 |
setProperties(properties) | 设置配置属性 |
isCollection(type) | 判断是否为集合类型 |
ObjectFactory 接口很简单,它包含两个创建实例用的方法,一个是处理默认无参构造方法的,另外一个是处理带参数的构造方法的。
默认无参构造方法示例:
ObjectFactory objectFactory = new DefaultObjectFactory();
Person person = objectFactory.create(Person.class);
带参数的构造方法示例:
ObjectFactory objectFactory = new DefaultObjectFactory();
Person person = objectFactory.create(Person.class,
Arrays.asList(Integer.class, String.class, String.class),
Arrays.asList(1, "小ben马", "小ben马"));
如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现。eg:
public class PersonObjectFactory extends DefaultObjectFactory {
// 定义额外属性
private Properties properties;
@Override
public Object create(Class type) {
if (type.equals(Person.class)) {
Person person = (Person) super.create(type);
person.setNickName(UUID.randomUUID().toString());
return person;
}
return super.create(type);
}
@Override
public void setProperties(Properties properties) {
this.properties = properties;
}
}
<!-- mybatis-config.xml -->
<objectFactory type="tech.ibit.mybatis.learning.common.tools.factory.PersonObjectFactory">
<!--设置其他属性-->
<property name="someProperty" value="100"/>
</objectFactory>
另外,setProperties 方法可以被用来配置 ObjectFactory,在初始化你的 ObjectFactory 实例后, objectFactory 元素体中定义的属性会被传递给 setProperties 方法。
ProxyFactory
ProxyFactory 是 Mybatis 中的代理工厂,主要用于动态代理对象。 ProxyFactory 两个实现,JavassistProxyFactory(支持Javassist动态代理) 和 CglibProxyFactory(支持Cglib动态代理)。ProxyFactory 主要用于 Mybatis 的懒加载功能。当开启懒加载后,Mybatis 创建 Mapper 映射结果对象后,会通过 ProxyFactory 创建映射结果对象的代理对象。当我们调用代理对象的 Getter 方法获取数据时,会执行 JavassistProxyFactory 或 CglibProxyFactory 中定义的拦截逻辑,然后执行一次额外的查询。
ProxyFactory 主要方法
方法 | 说明 |
---|---|
createProxy(target, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs) | 创建代理 |
示例代码
JavassistProxyFactory示例
// 创建ProxyFactory对象
ProxyFactory proxyFactory = new JavassistProxyFactory();
Person person = new Person(1, "小ben马", "小ben马");
ObjectFactory objectFactory = new DefaultObjectFactory();
// 调用ProxyFactory对象的createProxy()方法创建代理对象
Object proxyOrder = proxyFactory.createProxy(
person,
new ResultLoaderMap(),
new Configuration(),
objectFactory,
Arrays.asList(Integer.class, String.class, String.class),
Arrays.asList(person.getPersonId(), person.getPersonName(), person.getNickName())
);
System.out.println(proxyOrder.getClass());
System.out.println(((Person) proxyOrder).getPersonName());
输出结果>>>
class tech.ibit.mybatis.learning.common.tools.entity.Person_$$_jvst5_0
小ben马
CglibProxyFactory示例
// 创建ProxyFactory对象
ProxyFactory proxyFactory = new CglibProxyFactory();
Person person = new Person(1, "小ben马", "小ben马");
ObjectFactory objectFactory = new DefaultObjectFactory();
// 调用ProxyFactory对象的createProxy()方法创建代理对象
Object proxyOrder = proxyFactory.createProxy(
person,
new ResultLoaderMap(),
new Configuration(),
objectFactory,
Arrays.asList(Integer.class, String.class, String.class),
Arrays.asList(person.getPersonId(), person.getPersonName(), person.getNickName())
);
System.out.println(proxyOrder.getClass());
System.out.println(((Person) proxyOrder).getPersonName());
需要引入 cglib 相关依赖包。
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
输出结果>>>
class tech.ibit.mybatis.learning.common.tools.entity.Person$$EnhancerByCGLIB$$bfe52ae9
小ben马