详解Spring多数据源如何切换

 更新时间:2024年06月30日 11:21:17   作者:Bug生产猿  
这篇文章主要介绍了spring多数据源的如何切换,由于是spring项目,可以借助 spring 的DataSource 对象去管理,大体思路是创建一个类实现该接口,替换spring原有的DataSource 对象,文中有详细的代码示例供大家参考,需要的朋友可以参考下

由于是spring项目,可以借助 spring 的DataSource 对象去管理,大体思路是创建一个类(比如MyRoutingDataSource)实现该接口,替换spring原有的DataSource 对象,通过MyRoutingDataSource 管理需要spring真实的干活的数据源,这是属于哪种设计模式??

spring jdbc 已经考虑到了,继承spring中 AbstractRoutingDataSource 抽象类实现determineCurrentLookupKey 方法,setTargetDataSources方法用map形式传入所需要切换数据源,是模板方法设计模式??

在Spring框架中实现多数据源配置并切换通常涉及以下步骤:

1.定义数据源

在Spring配置文件中(XML或Java Config)定义多个DataSource bean。

 2.配置JPA或MyBatis

如果你使用JPA,你可能需要为每个数据源配置一个EntityManagerFactoryTransactionManager。如果你使用MyBatis,你可能需要为每个数据源配置一个SqlSessionFactorySqlSessionTemplate

3.使用@Qualifier 或 @Primary

当你有多个相同类型的bean时,你可以使用@Qualifier注解来指定要注入的bean。或者,你可以使用@Primary注解来标记一个数据源作为主要的,以便在不需要明确指定时自动注入。

4.实现数据源路由

数据源路由是实现多数据源切换的关键。你可以通过继承AbstractRoutingDataSource来创建自定义的数据源,该数据源可以根据当前线程或请求上下文中的某个标识符来切换数据源。

5.使用AOP或拦截器设置数据源

在请求处理之前,你可以使用AOP或拦截器来设置当前线程的数据源标识符。这样,当数据访问层(如JPA仓库或MyBatis Mapper)尝试获取数据源时,它将通过你的自定义数据源路由逻辑来获取正确的数据源。

示例代码

自定义数据源路由

public class DynamicDataSource extends AbstractRoutingDataSource {  
  
    @Override  
    protected Object determineCurrentLookupKey() {  
        // 这里可以根据需要返回不同的数据源标识符  
        // 例如,从ThreadLocal中获取当前线程的数据源标识符  
        return DataSourceContextHolder.getCurrentDataSource();  
    }  
}  
  
// 用于保存当前线程的数据源标识符的工具类  
public class DataSourceContextHolder {  
  
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();  
  
    public static void setCurrentDataSource(String dataSource) {  
        contextHolder.set(dataSource);  
    }  
  
    public static String getCurrentDataSource() {  
        return contextHolder.get();  
    }  
  
    public static void clearCurrentDataSource() {  
        contextHolder.remove();  
    }  
}

配置数据源

@Configuration  
public class DataSourceConfig {  
  
    @Bean(name = "primaryDataSource")  
    @ConfigurationProperties(prefix = "spring.datasource.primary")  
    public DataSource primaryDataSource() {  
        // ... 配置并返回DataSource 
        return DataSourceBuilder.create().build(); 
    }  
  
    @Bean(name = "secondaryDataSource")  
    @ConfigurationProperties(prefix = "spring.datasource.secondary")  
    public DataSource secondaryDataSource() {  
        // ... 配置并返回DataSource  
        return DataSourceBuilder.create().build();
    }  
  
    @Bean(name = "dataSource")  
    public DataSource dynamicDataSource() {  
        DynamicDataSource dataSource = new DynamicDataSource();  
        Map<Object, Object> targetDataSources = new HashMap<>();  
        targetDataSources.put("primary", primaryDataSource());  
        targetDataSources.put("secondary", secondaryDataSource());  
        dataSource.setTargetDataSources(targetDataSources);  
        dataSource.setDefaultTargetDataSource(primaryDataSource());  
        return dataSource;  
    }  
  
    // 配置其他必要的组件,如EntityManagerFactory和TransactionManager(如果需要)  
}

使用AOP或拦截器设置数据源

@Aspect  
@Component  
public class DataSourceAspect {  
  
    @Pointcut("@annotation(customDataSource)")  
    public void dataSourcePointcut(CustomDataSource customDataSource) {}  
  
    @Before("dataSourcePointcut(customDataSource)")  
    public void switchDataSource(JoinPoint joinPoint, CustomDataSource customDataSource) {  
        DataSourceContextHolder.setCurrentDataSource(customDataSource.value());  
    }  
  
    @After("@annotation(customDataSource)")  
    public void restoreDataSource(JoinPoint joinPoint, CustomDataSource customDataSource) {  
        DataSourceContextHolder.clearCurrentDataSource();  
    }  
}  
  
// 自定义注解,用于指定数据源  
@Target({ElementType.METHOD, ElementType.TYPE})  
@Retention(RetentionPolicy.RUNTIME)  
public @interface CustomDataSource {  
  
    String value() default "primary";  
}

现在,你可以在需要指定数据源的方法上使用@CustomDataSource注解来切换数据源。在方法执行之前,AOP切面将设置当前线程的数据源标识符,并在方法执行后清除它。这样,数据访问层就可以通过DynamicDataSource获取正确的数据源了。

到此这篇关于详解Spring多数据源如何切换的文章就介绍到这了,更多相关Spring多数据源切换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Maven如何打入依赖中指定的部分jar包

    Maven如何打入依赖中指定的部分jar包

    当项目运行的环境里已经有一个jar包是pom文件依赖其他项目的jar包,所以最后得到的项目jar包中还需要打入其他项目的最新代码,接下来通过本文给大家介绍Maven打入依赖jar包的操作工程,需要的朋友参考下吧
    2021-06-06
  • 分享Java死锁的4种排查工具

    分享Java死锁的4种排查工具

    这篇文章主要介绍了分享Java死锁的4种排查工具,死锁指的是两个或两个以上的运算单元,都在等待对方停止执行,以取得系统资源,但是没有一方提前退出,就称为死锁,下文更多相关内容需要的小伙伴可以参考一下
    2022-05-05
  • Java Servlet 表单数据处理详解

    Java Servlet 表单数据处理详解

    本文详细介绍了Servlet处理表单数据的方法,涵盖配置Servlet、获取参数、数据验证及响应内容设置,深入探讨 Servlet 如何接收、处理和响应表单数据,并提供一些最佳实践,以确保数据处理的正确性和安全性,感兴趣的朋友一起看看吧
    2026-05-05
  • Spring BeanFactory和FactoryBean有哪些区别

    Spring BeanFactory和FactoryBean有哪些区别

    这篇文章主要介绍了Spring BeanFactory 与 FactoryBean 的区别详情,BeanFactory 和 FactoryBean 的区别却是一个很重要的知识点,在本文中将结合源码进行分析讲解,需要的小伙伴可以参考一下
    2023-02-02
  • Java实现简易学生管理系统

    Java实现简易学生管理系统

    这篇文章主要为大家详细介绍了Java实现简易学生管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • MybatisPlus中插入数据后获取该对象主键值的实现

    MybatisPlus中插入数据后获取该对象主键值的实现

    这篇文章主要介绍了MybatisPlus中插入数据后获取该对象主键值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Java获取上月份最后一天日期8位的示例代码

    Java获取上月份最后一天日期8位的示例代码

    这篇文章主要介绍了Java获取上月份最后一天日期8位,需要的朋友可以参考下
    2022-09-09
  • 一文读懂ava中的Volatile关键字使用

    一文读懂ava中的Volatile关键字使用

    volatile关键字的作用保证了变量的可见性(visibility)。被volatile关键字修饰的变量,如果值发生了变更,其他线程立马可见,避免出现脏读的现象。这篇文章主要介绍了ava中的Volatile关键字使用,需要的朋友可以参考下
    2020-03-03
  • 解读HttpServletRequestWrapper处理request数据流多次读取问题

    解读HttpServletRequestWrapper处理request数据流多次读取问题

    在Java Web开发中,获取HTTP请求参数是常见需求,本文详细讨论了通过POST方式获取参数的两种主要方法:使用request.getParameter()适用于application/x-www-form-urlencoded和multipart/form-data内容类型;而对于application/json类型的数据
    2024-10-10
  • spring boot 错误页面配置解决方案

    spring boot 错误页面配置解决方案

    这篇文章主要介绍了spring boot 错误页面配置解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10

最新评论