1、先spring的看配置文件:
<
bean
id
="sqlSessionFactory"
class
="org.mybatis.spring.SqlSessionFactoryBean"
>
<
property
name
="mapperLocations"
value
="classpath*:mybatis/mapper/*Mapper.xml"
>
property
>
<
property
name
="dataSource"
ref
="dataSource"
/>
bean
>
<
bean
class
="org.mybatis.spring.mapper.MapperScannerConfigurer"
>
<
property
name
="basePackage"
value
="com.dzm.mybatis.dao"
/>
<
property
name
="sqlSessionFactoryBeanName"
value
="sqlSessionFactory"
>
property
>
bean
>
2、第一个bean:
SqlSessionFactoryBean,首先我们看一下此类实现的接口:
FactoryBean
, InitializingBean,从实现的接口看出这是一个创建SqlSessionFactory的工厂bean
3、因为此类实现了InitializingBean,所以我们看一下
afterPropertiesSet
()方法有哪些操作,这个方法就一句话:
this
.
sqlSessionFactory
= buildSqlSessionFactory();构建SqlSessionFactory,我们来看一下此方法里面我们关心的部分:
//我们在spring的配置文件里面对
mapperLocations属性设置了值:
<
property
name
="mapperLocations"
value
="classpath*:mybatis/mapper/*Mapper.xml"
>
if
(!
isEmpty
(
this
.
mapperLocations
)) {
for
(Resource mapperLocation :
this
.
mapperLocations
) {
XMLMapperBuilder xmlMapperBuilder =
new
XMLMapperBuilder(mapperLocation.getInputStream(),
configuration, mapperLocation.toString(), configuration.getSqlFragments());
xmlMapperBuilder.parse();
}
}
这里有人就会问了,我输入的是value是字符串,为什么到这个方法里面就变成了
Resource[]
mapperLocations类型了呢,这个里面就涉及到spring的一个类型转换,会根据目标属性的类型进行相应的转换,这里使用的类型转换类是:ResourceArrayPropertyEditor,它会把这个路径转换成相应的具体的mapper文件。
this
.
sqlSessionFactoryBuilder
.build(configuration);
上面的
sqlSessionFactoryBuilder是此类里面的属性,直接new的
private
SqlSessionFactoryBuilder
sqlSessionFactoryBuilder
=
new
SqlSessionFactoryBuilder();
参数
configuration
是在buildSqlSessionFactory里面直接声明的:
configuration
=
new
Configuration();
到处为止,
SqlSessionFactory对象被构建好了。
4、第二个bean:
MapperScannerConfigurer,此类实现了
BeanDefinitionRegistryPostProcessor接口,我们看主要看一下postProcessBeanDefinitionRegistry方法:
public void
postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
ClassPathMapperScanner scanner =
new
ClassPathMapperScanner(registry);
scanner.setAddToConfig(
this
.
addToConfig
);
scanner.setAnnotationClass(
this
.
annotationClass
);
scanner.setMarkerInterface(
this
.
markerInterface
);
scanner.setSqlSessionFactory(
this
.
sqlSessionFactory
);
scanner.setSqlSessionTemplate(
this
.
sqlSessionTemplate
);
scanner.setSqlSessionFactoryBeanName(
this
.
sqlSessionFactoryBeanName
);
scanner.setSqlSessionTemplateBeanName(
this
.
sqlSessionTemplateBeanName
);
scanner.setResourceLoader(
this
.
applicationContext
);
scanner.setBeanNameGenerator(
this
.
nameGenerator
);
scanner.registerFilters();
scanner.scan(StringUtils.
tokenizeToStringArray
(
this
.
basePackage
, ConfigurableApplicationContext.
CONFIG_LOCATION_DELIMITERS
));
}
5、让我们来看一下
ClassPathMapperScanner类:它的scan方法将扫描属性
basePackage
配置的
包下面所有的接口,然后包装成
MapperFactoryBean的
BeanDefinition进行返回,我们每一个mapper对象都是通过
MapperFactoryBean生成返回的。后续再对MapperFactoryBean进行分析