您的位置:首页 > 编程语言 > Java开发

Insight MyBatis-Spring 解析过程,调用执行

2016-08-08 18:55 471 查看
看懂,再整理出来应该就是真明白了。

疑问:MyBatis-Spring集成,spring 是怎么样托管的?

看源码,这个过程应该是这样的:

1.spring配置文件中注册 MapperScannerConfigurer (看参考1),完成scan Mapper并定义为MapperFactoryBean。scan实现参考:Insight
context:component-scan 实现class scan。

public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor{

// AbstractApplicationContext.invokeBeanFactoryPostProcessors调用 core!
// Invoke factory processors registered as beans in the context.
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 类似context:component-scan 过程,scan指定package的Mapper 接口并注册到beanFactory。
// 1.create Scanner
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
scanner.setMarkerInterface(this.markerInterface);// addIncludeFilter
scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);// PropertyValues
// 2.Scanner.scan 注意super.doScan完成后beanDefinition 的处理
scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
}
}// 自定义 Scanner
public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {

/**
* Calls the parent search that will search and register all the candidates.
* Then the registered objects are post processed to set them as MapperFactoryBeans
*
*/
@Override
public Set doScan(String... basePackages) {
Set beanDefinitions = super.doScan(basePackages);
for (BeanDefinitionHolder holder : beanDefinitions) {
GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();

// the mapper interface is the original class of the bean
// but, the actual class of the bean is MapperFactoryBean !!!
definition.getPropertyValues().add("mapperInterface", definition.getBeanClassName());
definition.setBeanClass(MapperFactoryBean.class);
// 配置sqlSessionFactoryBeanName
definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName));
}
//...
}
}

...

2.在上述Mapper definition 初始化过程中,需要Inject sqlSessionFactory 也就是调用MapperFactoryBean.setSqlSessionFactory()方法。而在此过程中,首先需要初始化sqlSessionFactory(beanFactory 就是自底向上的完成bean的组装、初始化,链式反应,boom)。

public class MapperFactoryBean extends SqlSessionDaoSupport {
// set 注入
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
if (!this.externalSqlSession) {
// 根据sqlSessionFactory 构造sqlSession
// SqlSessionTemplate 典型的JDK Proxy 应用案例,实现事务的控制 !!!
this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
}
}
// return an instance of mapperInterface,直接用吧
public T getObject() throws Exception {
return getSqlSession().getMapper(this.mapperInterface);
}
}

...

3.上述2过程中涉及的sqlSessionFactory初始化

public class SqlSessionFactoryBean {

public void afterPropertiesSet() throws Exception {
// 处理过程类似文档 Building SqlSessionFactory without XML
this.sqlSessionFactory = buildSqlSessionFactory();
}
}

...

4.至此,MyBatis-Spring 托管解析、初始化完成。

...

参考:

// http://www.mybatis.org/spring/mappers.html Scanning for mappers
1.Using the  element.
2.Using the annotation @MapperScan
3.Using a classic Spring xml file and registering the MapperScannerConfigurer

// http://www.mybatis.org/mybatis-3/getting-started.html // demo1: Building SqlSessionFactory without XML
DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
// demo2: Acquiring a SqlSession from SqlSessionFactory
SqlSession session = sqlSessionFactory.openSession();
try {
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
} finally {
session.close();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring MyBatis-Spring
相关文章推荐