首页 > 其他分享 >spring/springboot 整合注解切换数据源

spring/springboot 整合注解切换数据源

时间:2023-09-01 17:23:37浏览次数:29  
标签:springboot 数据源 切换 spring 注解 public DataSource

springboot 整合注解切换数据源
1、Spring Boot的配置文件

# 数据源1
spring.datasource.druid.one.url=jdbc:mysql://localhost:3306/db1
spring.datasource.druid.one.username=root
spring.datasource.druid.one.password=123456

# 数据源2
spring.datasource.druid.two.url=jdbc:mysql://localhost:3306/db2
spring.datasource.druid.two.username=root
spring.datasource.druid.two.password=123456

2、创建数据源配置类
创建一个数据源配置类,用于配置多个数据源:

@Configuration
public class DataSourceConfig {

    @Bean(name = "oneDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.one")
    public DataSource dataSourceOne() {
        return new DruidDataSource();
    }

    @Bean(name = "twoDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.two")
    public DataSource dataSourceTwo() {
        return new DruidDataSource();
    }

}

3、创建动态数据源工厂类
创建一个动态数据源工厂类,用于根据不同的注解切换不同的数据源:

public class DynamicDataSource extends AbstractRoutingDataSource {

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    @Override
    protected Object determineCurrentLookupKey() {
        return contextHolder.get();
    }

    public static void setDataSourceKey(String dataSourceKey) {
        contextHolder.set(dataSourceKey);
    }

    public static void clearDataSourceKey() {
        contextHolder.remove();
    }

}
4、创建数据源切换注解
创建一个自定义的注解,用于标记需要切换的数据源:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UseDataSource {
    String value();
}

5、创建数据源切换切面类
创建一个切面类,用于根据注解的值切换数据源:

@Aspect
@Component
public class DataSourceAspect {

    @Around("@annotation(useDataSource)")
    public Object switchDataSource(ProceedingJoinPoint joinPoint, UseDataSource useDataSource) throws Throwable {
        try {
            DynamicDataSource.setDataSourceKey(useDataSource.value());
            return joinPoint.proceed();
        } finally {
            DynamicDataSource.clearDataSourceKey();
        }
    }

}

6、使用注解切换数据源
在需要切换数据源的方法或类上添加@UseDataSource注解,并指定需要切换的数据源的名称:

@Service
public class UserService {
    @Autowired
    private UserDao oneUserDao; // 使用数据源1的UserDao操作数据库1中的用户信息。
    @Autowired
    private UserDao twoUserDao; // 使用数据源2的UserDao操作数据库2中的用户信息。
    @UseDataSource("one") // 切换到数据源1。

spring 整合注解切换数据源
1、Spring的配置文件

<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <!-- 数据源1的配置 -->
</bean>

<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <!-- 数据源2的配置 -->
</bean>

2、创建数据源切换注解
创建一个自定义的注解,例如@DataSource,用于指定使用哪个数据源

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
    String value();
}

3、创建数据源切换切面
创建一个切面类,用于根据注解的值切换数据源

@Aspect
@Component
public class DataSourceAspect {
    @Around("@annotation(com.example.demo.annotation.DataSource)")
    public Object switchDataSource(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        DataSource ds = method.getAnnotation(DataSource.class);
        if (ds == null) {
            throw new RuntimeException("无法切换数据源,请在方法上添加@DataSource注解,并指定数据源名");
        }
        String dataSourceName = ds.value();
        DataSourceContextHolder.setDataSource(dataSourceName);
        return joinPoint.proceed();
    }
}

创建数据源上下文持有者类
创建一个数据源上下文持有者类,用于保存当前线程的数据源信息:

public class DataSourceContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    public static void setDataSource(String dataSourceName) {
        contextHolder.set(dataSourceName);
    }
    public static String getDataSource() {
        return contextHolder.get();
    }
    public static void clearDataSource() {
        contextHolder.remove();
    }
}

注入数据源Bean到Spring容器中
将多个数据源的Bean注入到Spring容器中:

@Configuration
public class DataSourceConfig {
    @Bean(name = "dataSource1")
    public DataSource dataSource1() {
        return new BasicDataSource();
    }
    @Bean(name = "dataSource2")
    public DataSource dataSource2() {
        return new BasicDataSource();
    }
}

标签:springboot,数据源,切换,spring,注解,public,DataSource
From: https://www.cnblogs.com/ArthurHenry/p/17672442.html

相关文章

  • spring boot 结合 kafaka
    SpringBoot可以与ApacheKafka集成:添加Maven依赖:在您的SpringBoot项目的pom.xml文件中添加以下Maven依赖:<dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId><version>2.8.1</......
  • SpringSecurity简明教程
    SpringSecurity主要实现UserDetailsService来验证登录的用户信息,和Security的配置类来对登录方式和资源进行限制。案例包含利用数据库进行登录验证、URL访问限制、自定义登录页和利用ajax方式登录、实现自定义过滤器对验证码进行验证,完整代码在https://github.com/say-hey/sprin......
  • Spring源码分析(十三)ApplicationContext详解(下)
    前面两篇文章,已经对ApplicationContext的大部分内容做了介绍,包括国际化,Spring中的运行环境,Spring中的资源,Spring中的事件监听机制,还剩唯一一个BeanFactory相关的内容没有介绍,这篇文章就来介绍BeanFactory,这篇文章介绍,关于ApplicationContext相关的内容总算可以告一段落了。本文对应......
  • SpringCloud 支持 超大上G,多附件上传
    ​ 这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数下面直接贴代码吧,一些难懂的我大部分都加上注释了:上传文件实体类:看得出来,实体类中已经有很多我们需要的功能了,还有实用的属性。如MD5秒传的信息。pub......
  • spring容器加载
    1:准备加载Bean工厂---首先肯定告诉我们的程序,我需要加载容器了,从哪里开始加载,可能是从classpath(XML)或者Annotation(注解),接着spring会执行refresh()方法这个方法首先会判断当前是否有容器,如果有的话就关闭,没有就创建2:获得Bean工厂-----spring会解析我们的配置文件,把配置信息,解析成Be......
  • springcloud 跨域问题解决
    问题原因跨域本质是浏览器基于同源策略的一种安全手段同源策略(Sameoriginpolicy),是一种约定,它是浏览器最核心也最基本的安全功能所谓同源(即指在同一个域)具有以下三个相同点协议相同(protocol)主机相同(host)端口相同(port)反之非同源请求,也就是协议、端口、主机其中一项不相同的......
  • Spring 相关 Maven 依赖包
    <?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache......
  • SpringAMQP--消息转换器
        ......
  • SpringAMQP--TopicExchange
             ......
  • SpringAMQP-WorkQueue模型
          ......