Spring整合Mybatis源码流程
2024-01-22 21:44:14 0 举报
Spring整合Mybatis源码详细流程图
作者其他创作
大纲/内容
使用Spring整合Mybatis:1. 在配置类上使用@MapperScan(\"backage\"),指定Mapper路径2. 配置Mybatis的SqlSessionFactoryBean,并设置数据源
@MapperScan(\"com.mapper\")注解
MapperScannerRegistrar,会在配置类解析阶段,解析Import注解时生成BeanDefinition
@MapperScan除配置Mapper扫描路径外,额外会导入一个类@Import(MapperScannerRegistrar.class),用来注册Mapper接口扫描器,并注册为BeanDefinition
如果没有从Spring事务管理器中拿到SqlSession,那么会新建一个SqlSession连接if (session == null)session = sessionFactory.openSession(executorType);
这里调用的是ClassPathMapperScanner 重写的方法doScan(basePackages);
看返回类型,这里就是创建一个SqlSessionFactory public SqlSessionFactory getObject()
修改包含规则,Spring在进行包扫描判断包含规则时会直接返回true,不会去匹配@Component注解scanner.registerFilters();
mybatis的一级缓存在整合Spring后失效问题就体现在这里:因为一级缓存作用域是SqlSession级别的,这里如果没有开启事务,每次执行Mapper接口都会重新创建一个Sqlsession,所以一级缓存会失效,但是如果开启了Spring事务,会从threadLocal中获取Sqlsession,一级缓存又能正常使用了
这里就知道SqlSessionFactory的实际实现类是DefaultSqlSessionFactoryreturn new DefaultSqlSessionFactory(config);
设置根据类型自动注入definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
getSqlSession().getMapper(this.mapperInterface);
afterPropertiesSet();
SqlSessionInterceptor的invoke方法
找到sqlSessionTemplate使用的地方:可以看出它是定义在MapperFactoryBean的父类SqlSessionDaoSupport中的
调用父类Spring的扫描器,将接口扫描成BeanDefinition,注意:Mybatis重写了匹配规则使接口也能成功扫描成BeanDefinition,扫描逻辑详见连接Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
生成Mybatis的代理对象MapperFactoryBean.getObject()
前面我们提到Spring整合Mybatis需要配置一个SqlSessionFactoryBean它也继承FactoryBean接口,也是一个FactoryBean。直接看它的GetObject方法
真正的Sqlsession的创建其实是这代理逻辑中实现的getSqlSession()
用Spring本身的属性注入方式设置接口definition.getPropertyValues().add(\"addToConfig\
scanner.scan()开始扫描
处理mapper接口,使接口变成FactoryBean类型processBeanDefinitions(beanDefinitions);
SqlSessionFactory的创建
sqlSessionTemplate的创建需要SqlSessionFactory是一个Bean,这里需要找到SqlSessionFactory是在哪里成为Bean的?
sqlSessionTemplate.getMapper()
使用构造方法为属性赋值,这里其实就是将接口赋值到FactoryBean中definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
MapperScannerConfigurer.postProcessBeanDefinitionRegistry()
createSqlSessionTemplate(sqlSessionFactory)
在这个方法中会注册一个MapperScannerConfigurer的BeanDefinition,这个类又继承BeanDefinitionRegistryPostProcessor,是一个BeanFactoryProcessor,会在配置类全部解析完成后调用postProcessBeanDefinitionRegistry()方法
设置BeanClass,这个FactoryBean就是用来生成Mybatis操作数据库代理对象的类definition.setBeanClass(this.mapperFactoryBeanClass);
ClassPathMapperScanner 重写了Spring的ClassPathBeanDefinitionScanner,支持接口生成BeanDefinitionClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
this.sqlSessionFactory = buildSqlSessionFactory();
sqlSessionTemplate创建
从这里可以看出,Mybatis的动态代理是使用的sqlSessionTemplate创建的,更不整合Spring有所区别
this.sqlSessionFactoryBuilder.build(targetConfiguration);
MapperScannerRegistrar继承了ImportBeanDefinitionRegistrar接口,会在配置解析完后调用它的registerBeanDefinitions
mapperProxyFactory.newInstance(sqlSession);
sqlSessionTemplate创建具体实现
MapperScannerConfigurer.postProcessBeanDefinitionRegistry()方法,这里面就会进行Mapper接口扫描,并将接口包装成FactoryBean类型,注册到BeanDefinitionMap中
在font color=\"#323232\
0 条评论
下一页