本文介绍: Target({@Target({@Target({//切面,略微有些问题,根据自己需要修改@Aspect@Componentif(signature instanceof MethodSignature ms){// java 17写法//方法上的注解//class上的注解//设置数据源

1.数据库配置

spring:
  datasource:
    # 默认数据源
    default:
      url: jdbc:mysql://localhost:3306/maindb
      username: default
      password: depassword
      driver-class-name: com.mysql.cj.jdbc.Driver

    # 第二个数据源
    second:
      url: jdbc:mysql://localhost:3306/seconddb
      username: second
      password: secondpassword
      driver-class-name: com.mysql.cj.jdbc.Driver

2.创建数据源Bean

@Configuration
@EnableTransactionManagement
public class MultipleDataSourceConfig {
   @Bean(name ="default")
   @ConfigurationProperties(prefix = "spring.datasource.default")
   public DataSource default(){
      return DataSourceBuilder.create.build():
   }

   @Bean(name ="second")
   @ConfigurationProperties(prefix = "spring.datasource.second")
   public DataSource second(){
      return DataSourceBuilder.create.build():
   }

}
//上下文数据设置
public class DynamicDataSourceContext(){
  
  private static ThreadLocal<String> contextHolder = null;
  synchronized public static ThreadLocal<String> getInstance() {
     if (contextHolder == null) {
        contextHolder = new ThreadLocal<>();
     }
     return contextHolder;
  }
 public static void setDataSource(String dataSource) {
      getInstance().set(dataSource);
 }
 
 public static String getDataSource(){
     return Objects.isNull(getInstance().get()) ? "default": getDataSource().get();
 }

 public static void clearDataSource(){
    getInstance().remove();
 }
}
//AbstractRoutingDataSource 是 Spring 提供的一个抽象类,用于支持在运行时动态切换数据源。它允许根据特定的标识符来选择要使用数据源,这样您可以根据需要在不同的情况下选择不同的数据源。

//AbstractRoutingDataSource 中的 determineCurrentLookupKey() 方法是一个抽象方法,您需要在自定义数据路由类中覆盖方法。它的作用是确定当前使用数据源的标识符,通常用来从一些上下文信息获取数据源的标识。

public class DynamicDataSource extends AbstractRoutingDataSource {

   @Override
   protected Object determineCurrentLookupKey(){
        return DynamicDataSourceContext.getDataSource();
   }
}
@Configuration
public class DynamicDataSourceConfig {
   
   @Bean
   @Primary
   public DataSource dataSOurce(@Qualifier("default") DataSource defeult,@Qualifier("second") DataSource second){
      Map<Object,Object> datasource = new HashMap();
      datasource.put("default",defeult);
      datasource.put("second",second);
      DynamicDataSource dynamicDataSource = new DynamicDataSource();
      dynamicDataSource.setTargetDataSources(datasource);
      dynamicDataSource.setDefaultTargetDataSource(default);
      return dynamicDataSource;
   } 
}

3.定义注解设置具体数据

import java.lang.annotation.*;

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

//切面,略微有些问题,根据自己需要修改

@Aspect
@Component
public class DataSourceAspect {

    @Pointcut("@annotation(xx.xx.xxx.DynamicDataSourceSwitch)")
    public void myCustomAnnotationPointcut() {
    }

    @Before("myCustomAnnotationPointcut()")
    public void beforeMyCustomAnnotation( JoinPoint point) {
       Signature signature = point.getSignature();
       DynamicDataSourceSwitch switercher;
       if(signature instanceof MethodSignature ms){// java 17写法
           //方法上的注解
           switercher = ms.getMethod().getAnnotation(DynamicDataSourceSwitch.class);
           if(Objects.isNull(switercher)){
             //class上的注解
             switercher = (DynamicDataSourceSwitch)signature.getDeclaringType().getAnnotation(DynamicDataSourceSwitch.class);
           }
           if(Objects.nonNull(switercher)) {
           //设置数据源
             DynamicDataSourceContext.setDataSource(switercher.value);
           }
       }
    }

    @After("myCustomAnnotationPointcut()")
    public void afterMyCustomAnnotation(JoinPoint point) {
        DynamicDataSourceContext.clearDataSource();
    }

    @AfterThrowing(pointcut = "myCustomAnnotationPointcut()")
    public void afterThrowingMyCustomAnnotation(JoinPoint point) {
        DynamicDataSourceContext.clearDataSource();
    }
}

4.使用

@Service
@DynamicDataSourceSwitch("second")
public class TestService {
  public void test(){
  //你的逻辑
  }
}

原文地址:https://blog.csdn.net/ks2356/article/details/134667100

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_3593.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注