如果你阅读过
mybatis-spring整合包源码阅读(一)---- SqlSessionFactoryBean相关总结
mybatis-spring整合包源码阅读(二)---- MapperScannerRegistrar 相关总结
你就会对spring整合Mybatis有个大概的了解,spring与mybatis的整合,实际上就是使用spring的ClassPathBeanDefinitionScanner
能力,来对指定包名下的DAO类解析成多个由MapperFactoryBean
包裹的BeanDefinition
,同时这些BeanDefinition
具有@Autowired
注解能力。
为什么要说MapperFactoryBean
?
因为他是spring整合Mybatis运行的一个关键点,有了这个类,你才能获取到Mybatis的代理对象
一、看继承类和实现的接口
public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T>
SqlSessionDaoSupport
见名知意:DAO支持类
FactoryBean
这个就不用过多解释了吧,spring获取对象的一个工厂类
1、先说 SqlSessionDaoSupport
继承关系图
MapperFactoryBean<T>
作为SqlSessionDaoSupport
的子类,它可以使用spring的后置处理器,
DaoSupport的后置处理代码如下
public final void afterPropertiesSet() throws IllegalArgumentException, BeanInitializationException {
// 关键点在这里checkDaoConfig
this.checkDaoConfig();
try {
this.initDao();
} catch (Exception var2) {
throw new BeanInitializationException("Initialization of DAO failed", var2);
}
}
MapperFactoryBean<T>
重构了checkDaoConfig()方法,源码如下
@Override
protected void checkDaoConfig() {
super.checkDaoConfig();
notNull(this.mapperInterface, "Property 'mapperInterface' is required");
// 构建Mybatis的配置类,如果你好奇为什么这里调用getSqlSession不会NPE
// 你可以仔细看看 mybatis-spring整合包源码阅读(二)中,创建 BeanDefinition 的代码
Configuration configuration = getSqlSession().getConfiguration();
if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {
try {
// mapperInterface 是在创建 BeanDefinition 时,提供一个一个有参数的构造方法,参数就是mapperInterface.class
// 此处就是Mybatis原生添加MapperProxyFactory<T>的方法,具体可以查看mybatis的相关源码
configuration.addMapper(this.mapperInterface);
} catch (Exception e) {
logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", e);
throw new IllegalArgumentException(e);
} finally {
ErrorContext.instance().reset();
}
}
}
目前为止,spring 与mybatis的整合中如何创建的代理对象,到这里相信你应该明白了,如果不懂,建议慢慢看一次