一文搞懂MyBatis多数据源Starter实现

 前言

本文将实现一个MyBatisSpringbootStarter包,引用这个Starter包后,仅需要提供少量配置信息,就能够完成MyBatis多数据源的初始化和使用,相较于MyBatis官方的Starter包,扩展了多数据源的使用场景。

本文的所有源码可以从如下仓库下载。

multidatasource GitHub

Springboot版本:2.7.6

正文

一. 实现思路

要实现Starter包,肯定需要借助Springboot的自动装配机制,所以我们首先需要提供自动装配的配置类。

然后我们需要加载多个数据源的配置并且生成对应的数据源,同时还需要可以根据用户配置的type创建不同的数据源,例如可以支持创建HikariCPDruidTomcatJdbc的数据源。

创建出来的数据源需要根据用户的配置,设置给不同的SqlSessionFactory,然后不同的SqlSessionFactory设置给不同的MapperScannerConfigurer,最终实现的效果就是一部分映射接口使用一个数据源,另一部分映射接口使用另一个数据源。

最后,还需要提供一种手段,抑制Springboot原生的数据源加载,这个功能我们可以通过ApplicationContextInitializer这个扩展点来完成。

整体的一个思维导图如下所示。

二. 自动装配实现

由于适配的是Springboot2.7.x版本,所以需要在resources\META-INF\spring目录下创建org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,且内容如下所示。

com.lee.multidatasource.autoconfig.LeeMultiPersistenceAutoConfiguration
复制代码

上述的LeeMultiPersistenceAutoConfiguration就是完成自动装配的配置类,实现如下。

@AutoConfiguration
@Import({LeeMultiPersistenceConfiguration.class, DataSourceBeanPostProcessor.class,})
public class LeeMultiPersistenceAutoConfiguration {}
复制代码

通过LeeMultiPersistenceAutoConfiguration导入了两个bean,一个是LeeMultiPersistenceConfiguration,用于加载配置以及创建数据源和MyBatisbean,另一个是DataSourceBeanPostProcessor,用于对LeeMultiPersistenceConfiguration创建的bean做一些后置处理。

上述就是自动装配的实现,主要就是将LeeMultiPersistenceAutoConfiguration注册到容器中,而LeeMultiPersistenceAutoConfiguration也是整个Starter包实现的关键。

三. 配置加载

约定数据源和MyBatis的配置需要遵循如下规则。

lee:
  persistence:
    dataSourceName1:
      datasource:
        type: ...
        max-lifetime: ...
        keep-alive-time: ...
        driver-class-name: ...
        url: ...
        username: ...
        password: ...
        pool-name: ...
      mybatis:
        configLocation: ...
        basePackage: ...
    dataSourceName2:
      datasource:
        max-lifetime: ...
        keep-alive-time: ...
        driver-class-name: ...
        url: ...
        username: ...
        password: ...
        pool-name: ...
      mybatis:
        configLocation: ...
        basePackage: ...
复制代码

lee.persistence的下一级的配置,是数据源的名字,可以由用户自定义,这个名字最终会作为数据源的beanIOC容器中的名字。

lee.persistence.dataSourceName的下一级的配置,固定是两个配置项,其一是lee.persistence.dataSourceName.datasource,用于设置数据源相关的配置,其二是lee.persistence.dataSourceName.mybatis,用于设置MyBatis相关的配置。

由于数据源的名字和个数都可以由用户自定义,那么很难基于@ConfigurationProperties注解来一步到位的完成上述数据源配置的加载,我们需要基于Environment来自行处理。

下面来看一下用于处理数据源配置的LeeMultiPersistenceConfiguration的类图,如下所示。

LeeMultiPersistenceConfiguration首先实现了EnvironmentAware接口,从而可以拿到Environment对象,其次实现了ImportBeanDefinitionRegistrar接口,从而可以向Spring注册BeanDefinition,那么实际上LeeMultiPersistenceConfiguration做的事情就是加载配置以及向Spring注册数据源和MyBatis相关组件的BeanDefinition。下面看一下LeeMultiPersistenceConfiguration实现的registerBeanDefinitions() 方法。

@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                                    BeanDefinitionRegistry registry) {
    // 加载并解析数据源配置
    MultiPersistenceProperties multiPersistenceProperties = parseMultiPersistenceProperties();
    List<String> persistenceNames = multiPersistenceProperties.getPersistenceNames();
    // 为每个数据源注册BeanDefinition
    for (String persistenceName : persistenceNames) {
        registerDatasource(registry, persistenceName, multiPersistenceProperties.getDataSourceProperties(persistenceName));
        registerSqlSessionFactory(registry, persistenceName, multiPersistenceProperties.getMybatisProperties(persistenceName));
        registerMapperScannerConfigurer(registry, persistenceName, multiPersistenceProperties.getMybatisProperties(persistenceName));
    }
}
复制代码

本节就先分析一下数据源配置的加载和解析,具体就是LeeMultiPersistenceConfigurationparseMultiPersistenceProperties() 方法,如下所示。

private MultiPersistenceProperties parseMultiPersistenceProperties() {
    MultiPersistenceProperties multiPersistenceProperties = new MultiPersistenceProperties();
    // 将数据源相关的配置加载为MultiPersistencePropertiesWrapper
    MultiPersistencePropertiesWrapper multiPersistencePropertiesWrapper = parseMultiPersistencePropertiesWrapper();
    List<String> persistenceNames = multiPersistencePropertiesWrapper.getPersistenceNames();
    // 遍历每一个数据源并拿到这个数据源下数据源相关配置和MyBatis相关配置
    for (String persistenceName : persistenceNames)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值