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。
...
2.在上述Mapper definition 初始化过程中,需要Inject sqlSessionFactory 也就是调用MapperFactoryBean.setSqlSessionFactory()方法。而在此过程中,首先需要初始化sqlSessionFactory(beanFactory 就是自底向上的完成bean的组装、初始化,链式反应,boom)。
...
3.上述2过程中涉及的sqlSessionFactory初始化
...
4.至此,MyBatis-Spring 托管解析、初始化完成。
...
参考:
疑问: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(); }
相关文章推荐
- mybatis源码学习之执行过程分析(2)——config.xml配置文件和mapper.xml映射文件解析过程
- mybatis源码解析(三)-SqlSession.selectOne类似方法调用过程
- SSM的Web程序执行过程(Spring SpringMVC Mybatis)
- 【Mybatis源码剖析】Spring中获取 Mybatis Mapper接口(注解Autowired),并调用过程剖析
- MyBatis 源码解析:通过源码深入理解 SQL 的执行过程
- Spring基本执行过程解析
- MyBatis 源码解析:通过源码深入理解 SQL 的执行过程
- mybatis_sql执行过程源码解析
- Mybatis之是如何执行你的SQL的(SQL执行过程,参数解析过程,结果集封装过程)
- Mybatis源码解析-Mapper执行SQL过程
- mybatis源码解析(四)-Mapper方法调用过程
- 【spring源码学习】springMVC之映射,拦截器解析,请求数据注入解析,DispatcherServlet执行过程
- Insight spring @Scheduled 解析过程
- java方法调用过程解析和执行--编译器的处理
- 关于调用Spring设置Quartz中动态执行时间解决办法
- 解析在ASP.NET中调用存储过程的方法
- 导出Excel执行 Render() 的过程中调用 RegisterForEventValidation
- 只能在执行 Render() 的过程中调用 RegisterForEventValidation(RegisterForEventValidation can only be called during Render(); )
- 只能在执行 Render() 的过程中调用 RegisterForEventValidation(RegisterForEventValidation can only be called during Render()
- 当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用