- MybatisPlusInterceptor(since 3.4.0)是核心插件,目前代理了 Executor#query 和 Executor#update 和 StatementHandler#prepare 方法
- 使用方式(以分页插件举例)
从上图可以看出MybatisMapperProxy初始化的入口在MapperFactoryBean#getObject
- 指定mapper包路径@MapperScan(basePackages = {“xxxx”,“xxxx”})
- 重点关注MapperScannerRegistrar#registerBeanDefinitions
2.1 读取@MapperScan注解的basePackages属性值
2.2 将basePackage属性设置到MapperScannerConfigurer中
2.3 将MapperScannerConfigurer注册到spring容器中BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class); builder.addPropertyValue("processPropertyPlaceHolders", true); builder.addPropertyValue("basePackage", StringUtils.collectionToCommaDelimitedString(basePackages)); registry.registerBeanDefinition(beanName, builder.getBeanDefinition());
- MapperScannerConfigurer类实现BeanDefinitionRegistryPostProcessor接口
- 关注MapperScannerConfigurer#postProcessBeanDefinitionRegistry方法
2.1 扫描basePackage包下的mapper接口ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry); scanner.scan( StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)); - 扫描实现ClassPathBeanDefinitionScanner#scan
3.1 扫描的简易流程ClassPathBeanDefinitionScanner#scan --> ClassPathMapperScanner#doScan --> ClassPathMapperScanner#processBeanDefinitions
3.2 从上图可以发现mapper接口最终注册到spring容器中的是MapperFactoryBean
- 从上图的调用栈可以看出,mybatis-plus自动配置SessionFactory
- 重点关注MybatisSqlSessionFactoryBean#buildSqlSessionFactory
2.1 在方法中会判断是否设置插件拦截器属性
2.2 最终将插件添加到mybatis的拦截器链上Configuration$interceptorChain
2.2 解析xml文件
2.3 构建初始化生成SqlSessionFactory(DefaultSqlSessionFactory)
- 从上面的流程可以看出SQL操作最终通过代理方法SqlSessionInterceptor#invoke实现
- 在DefaultSqlSessionFactory#openSessionFromDataSource生成sqlSession时,将其configuration属性进行传递(包含插件链)
- 关注DefaultSqlSession#delete
- 根据配置生成StatementHandler:
- 遍历插件链,执行InterceptorChain#plugin方法
2.1 插件执行在解析参数和执行SQL之前
以上就是对插件分析,后面准备基于插件功能做一个SQL更新操作的diff功能



