思维导图
- mybatis
- 1.配置阶段
- 1.自动装配过程
- 2.接口扫描过程
- 3.接口动态代理
- 4.接口方法映射
- 2.运行阶段
- 1.接口方法执行
- 2.插件链的处理
- 1.配置阶段
配置阶段
源码版本:
<!-- pom.xml -->
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot</artifactId>
<version>2.2.1-SNAPSHOT</version>
自动装配过程
基于spring-autoconfig,SPI动态扩展
@startuml
class "MybatisAutoConfiguration" as mac {
- MybatisProperties properties
- Interceptor[] interceptors
- ResourceLoader resourceLoader
+ SqlSessionFactory sqlSessionFactory(DataSource dataSource)
+ SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory)
}
note left of mac
通过spring.factories文件
配置,类似java的SPI机制
主要功能:
1. 声明Bean: SqlSessionFactory
2. 声明Bean: SqlSessionTemplate
3. 创建Configuration
4. 配置Mapper扫描
end note
class "MybatisProperties" as mp{
- String configLocation
- String[] mapperLocations
- String typeAliasesPackage
- String typeHandlersPackage
- boolean checkConfigLocation
- ExecutorType executorType
- Properties configurationProperties
- Configuration configuration
+ Resource[] resolveMapperLocations()
}
note top of mp
yml配置文件中前缀为`mybatis`的配置项
声明config文件位置,还有yml中的配置
end note
class "AutoConfiguredMapperScannerRegistrar" as msr <<ImportBeanDefinitionRegistrar>> {
- BeanFactory beanFactory
+ void registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry)
}
note left of msr
实现ImportBeanDefinitionRegistrar接口
注入MapperScannerConfigurer实例,用于
配置扫描Mapper
end note
interface "BeanDefinitionRegistry" as bdr {
...
+ void registerBeanDefinition(String beanName, BeanDefinition)
}
interface "BeanDefinitionRegistryPostProcessor" as bdrpp <<BeanFactoryPostProcessor>>{
+ void postProcessBeanFactory(ConfigurableListableBeanFactory)
+ void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)
}
class "DefaultListableBeanFactory" as dlbf {
- Map<String, BeanDefinition> beanDefinitionMap
- volatile List<String> beanDefinitionNames
}
class "ClassPathBeanDefinitionScanner" as cpbds{
- BeanDefinitionRegistry registry
+ int scan(String... basePackages)
# Set<BeanDefinitionHolder> doScan(String... basePackages)
}
class "MapperScannerConfigurer" as msc <<BeanDefinitionRegistryPostProcessor>>{
- Class<? extends Annotation> annotationClass
- String basePackage
- 其他属性..
+ void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry)
}
class "ClassPathMapperScanner" as cpms{
- Class<? extends Annotation> annotationClass
- Class<? extends MapperFactoryBean> mapperFactoryBeanClass = MapperFactoryBean.class
+ void registerFilters()
+ Set<BeanDefinitionHolder> doScan(String... basePackages)
- void processBeanDefinitions(Set<BeanDefinitionHolder>)
}
note left of cpms::registerFilters
设置过滤,扫描Mapper注解
this.addIncludeFilter(new AnnotationTypeFilter(this.annotationClass));
end note
note left of cpms::processBeanDefinitions
核心处理方法,将扫描到的类设置为MapperFactoryBean.class
definition.setBeanClass(this.mapperFactoryBeanClass)
设置依赖sqlSessionFactory等
end note
interface "FactoryBean<T>" as fb {
+ String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType"
+ T getObject()
+ Class<?> getObjectType()
+ boolean isSingleton()
}
note left of fb::getObject
最终生成实例代理类
end note
class "DaoSupport" as ds <InitializingBean> {
+ void afterPropertiesSet()
+ void checkDaoConfig()
+ void initeDao()
}
note right of ds::afterPropertiesSet
调用checkDaoConfig,最终通
过Configuration.addMapper
添加mapper
end note
class "SqlSessionDaoSupport" as ssds extends ds {
+ void checkDaoConfig()
}
class "MapperFactoryBean" as mfb extends ssds implements fb {
- boolean addToConfig = true
- Class<T> mapperInterface
- SqlSessionTemplate sqlSessionTemplate
+ void checkDaoConfig()
+ T getObject()
}
note left of mfb::mapperInterface
业务代码定义的类,注解Mapper修饰
end note
note right of mfb::sqlSessionTemplate
通过模板获取到之前生成的configuration
配置
end note
note right of mfb::checkDaoConfig
重写,调用Configuration.addMapper添加
end note
note left of mfb::getObject
通过Configuration生成过去代理类
end note
class "Configuration" as cfg{
- MapperRegistry mapperRegistry
+ bool hasMapper(Class)
+ void addMapper(Class)
}
note left of cfg
MybatisProperties声明的文件位置,
MybatisAutoConfigurtion创建的配置
end note
class "MapperRegistry" as mr {
- Map<Class<?>, MapperProxyFactory<?>> knownMappers
+ boolean hasMapper(Class<T>)
+ void addMapper(Class<T>)
+ void getMapper(Class<T>, SqlSession)
}
note left of mr
注册Mapper,和生成Mapper代理工厂,
通过Mapper代理工厂最终生成代理类提供给
Spring容器
end note
class "MapperProxyFactory<T>" as mpf{
- Class mapperInterface
- Map<Method, MapperMethodInvoker> methodCache
+ T newInstance(SqlSession)
}
class "MapperProxy" as mproxy <<InvocationHandler>> {
- SqlSession sqlSession
- Class<T> mapperInterface
- Map<Method, MapperProxy.MapperMethodInvoker> methodCache
}
note left of mproxy
最终注入容器的JDK代理类,
解析定义的Mapper接口方法并缓存句柄
运行时执行
end note
mac::properties <- mp
mac <-- msr : @Import导入配置
msr::registerBeanDefinitions <. bdr
bdr <|.. dlbf: 注册信息保存在Map中
msr .[hidden]. bdrpp
msr <--- msc
bdrpp <|.. msc
msc <-- cpms
bdr <--- cpbds
cpbds <|.. cpms
cpms <--- mfb
fb .[hidden] (cpms, mfb)
mfb <-- cfg
cfg <-- mr
mr <-- mpf
mpf <-- mproxy
@enduml
运行阶段
Mybatis 接口方法执行流程
源码版本:
JDK8和JDK9之后稍有不同,之后版本方法通过方法句柄实现,功能一致,没有太大区别
@startuml
annotation Service
class XXService {
- mapper:IMapper
}
interface IMapper {
+ Object doSomething()
}
class MapperProxy <<InvocationHandler>> {
- SqlSession sqlSession
- Class<T> mapperInterface
- Map<Method, MapperMethod> methodCache
}
class MapperMethod {
- SqlCommand command
- MethodSignature method
+ Object execute(SqlSession sqlSession, Object[] args)
- Object rowCountResult(int rowCount)
}
class SqlCommand{
- String name
- SqlCommandType type
}
class MethodSignature {
- boolean returnsMany
- boolean returnsMap
- boolean returnsVoid
- Class<?> returnType
- String mapKey
- Integer resultHandlerIndex
- Integer rowBoundsIndex
- SortedMap<Integer, String> params
- boolean hasNamedParameters
+ Object convertArgsToSqlCommandParam(Object[] args)
+ RowBounds extractRowBounds(Object[] args)
+ ResultHandler extractResultHandler(Object[] args)
}
interface SqlSession {
- void select(...)
- List selectList(...)
}
class DefaultSqlSession {
- Executor executor
}
interface Executor {
+ List query(MappedStatement var1, Object var2, RowBounds var3, ResultHandler var4)
+ List query(...)
}
abstract class BaseExecutor implements Executor {
- PerpetualCache localCache
- List queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
# abstract List doQuery(MappedStatement var1, Object var2, RowBounds var3, ResultHandler var4, BoundSql var5)
}
class SimpleExecutor extends BaseExecutor{
+ List doQuery(MappedStatement var1, Object var2, RowBounds var3, ResultHandler var4, BoundSql var5)
}
interface StatementHandler {
+ List query(Statement var1, ResultHandler var2)
}
class RoutingStatementHandler {
- StatementHandler delegate
}
class Configuration {
- InterceptorChain interceptorChain
+ StatementHandler newStatementHandler(...)
}
class InterceptorChain{
- List<Interceptor> interceptors
+ Object pluginAll(Object target)
+ void addInterceptor(Interceptor interceptor)
}
interface Interceptor {
+ Object intercept(Invocation var1) throws Throwable
+ Object plugin(Object var1)
+ void setProperties(Properties var1)
}
class Plugin <<InvocationHandler>> {
- Object target
- Intercepor interceptor
- Map<Class<?>, Set<Method>> signatureMap
+ Object wrap(Object target, Interceptor interceptor)
}
interface ResultHandler {
+ List handleResultSets(Statement var1)
}
interface PreparedStatement {
+ void execute()
}
XXService .> Service
XXService <-- IMapper : 成员变量
XXService <-- MapperProxy : spring容器注入实例
MapperProxy -left- IMapper : JDK动态代理
MapperProxy o-- MapperMethod : Map缓存
MapperMethod -left> SqlCommand
MapperMethod -> MethodSignature
MapperMethod <.. SqlSession : execute参数调用
SqlSession <|-- DefaultSqlSession
DefaultSqlSession -> Executor
SimpleExecutor <.. StatementHandler : Plugin层层代理过后的实例
StatementHandler <|--- RoutingStatementHandler
StatementHandler <|--- PreparedStatementHandler
Configuration <.... RoutingStatementHandler : 构建并应用插件链
Configuration .> SimpleExecutor
Configuration <-- InterceptorChain
InterceptorChain o.. Interceptor: pluginAll层层包装target(JDK动态代理)
Interceptor <.. Plugin : Plugin.warp 包装成代理类
Interceptor --> Plugin
InterceptorChain .[hidden] StatementHandler
Plugin = RoutingStatementHandler : JDK动态代理
RoutingStatementHandler -- PreparedStatementHandler: 静态代理
PreparedStatement .> PreparedStatementHandler
PreparedStatementHandler <. ResultHandler
@enduml