本文介绍: 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进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。