目前动态数据源注解只对mapper.java做了适配,现在需要优化完善,可以针对 自动注入的mapp...

تم الإنشاء في: ٢٨ يناير ٢٠٢٦

تمت الإجابة باستخدام GPT-5.2 Thinking بواسطة Chat01

سؤال

目前动态数据源注解只对mapper.java做了适配,现在需要优化完善,可以针对 自动注入的mapper字段适配,mapper.java中的具体方法适配,已经目前已有的mapper方法类的适配。如果都有数据源注解,那么优先级 字段 > 方法 > 类,下面是已有代码

自定义注解

java
package com.wiscom.basic.config.datasource; import java.lang.annotation.*; @Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TargetDataSource { String name() default ""; }

数据源切换和注解解析

java
package com.wiscom.basic.config.datasource; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.util.Objects; @Component @Aspect @Slf4j @Order(-100) public class TargetDataSourceAspect { /** * 切入点:所有dao包下接口文件 */ @Pointcut("execution(* com.wiscom..*.service..*.*(..)) || execution(* com.wiscom..*.dao..*.*(..)) || execution(* com.wiscom..*.mapper..*.*(..))") private void dsPointCut() { } /** * 设置具体数据源 * * @param joinPoint 切点 * @return Object * @throws Throwable 异常 */ @Around("dsPointCut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { // 获取当前指定的获取mapper接口数据源 MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Class<?> targetInterface = ms.getDeclaringType(); TargetDataSource dataSource = targetInterface.getAnnotation(TargetDataSource.class); /* 没有匹配到的话,使用默认数据源,否则设置到动态数据源上下文中 */ if (Objects.isNull(dataSource)) { DynamicDataSource.setDataSource("elss"); log.debug("使用默认数据源"); } else { DynamicDataSource.setDataSource(dataSource.name()); log.debug("匹配到数据源:{}", dataSource.name()); } try { return joinPoint.proceed(); } finally { /* 方法执行完毕之后,销毁当前数据源信息,进行垃圾回收 */ DynamicDataSource.clearDataSource(); log.debug("当前数据源已清空"); } } }

其他方法

java
package com.wiscom.basic.config.datasource; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import javax.sql.DataSource; import java.util.Map; public class DynamicDataSource extends AbstractRoutingDataSource { private static final ThreadLocal<String> DB_CONTEXT_HOLDER = new ThreadLocal<>(); /** * 取得当前使用的数据源 * * @return 当前使用的数据源 */ @Override protected Object determineCurrentLookupKey() { return getDataSource(); } /** * 设置数据源 * * @param dataSource 数据源 */ public static void setDataSource(String dataSource) { DB_CONTEXT_HOLDER.set(dataSource); } /** * 获取当前数据源 * * @return 数据源 */ public static String getDataSource() { return DB_CONTEXT_HOLDER.get(); } /** * 清除上下文 */ public static void clearDataSource() { DB_CONTEXT_HOLDER.remove(); } /** * 设置默认数据源,和可切换的数据源Map * * @param defaultTargetDataSource 默认数据源 * @param targetDataSources 可切换的数据源Map */ public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) { super.setDefaultTargetDataSource(defaultTargetDataSource); super.setTargetDataSources(targetDataSources); super.afterPropertiesSet(); } }
java
package com.wiscom.basic.config.datasource; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; @Configuration @Component public class DataSourceConfig { /** * 配置弃电系统pgsql数据源 * * @return 数据源对象 */ @Bean(name = "elss") @ConfigurationProperties(prefix = "spring.datasource.elss") public DataSource pgsqlSource() { return DruidDataSourceBuilder.create().build(); } /** * 配置统调弃电数据源 * * @return 数据源对象 */ @Bean(name = "elss_centrally") @ConfigurationProperties(prefix = "spring.datasource.elss-centrally") @ConditionalOnProperty(prefix = "spring.datasource.elss-centrally", name = "url") public DataSource pgsqlElssCentrallySource() { return DruidDataSourceBuilder.create().build(); } /** * 配置可视化系统pgsql数据源 * * @return 数据源对象 */ @Bean(name = "envs") @ConfigurationProperties(prefix = "spring.datasource.envs") @ConditionalOnProperty(prefix = "spring.datasource.envs", name = "url") public DataSource pgsqlEnvsSource() { return DruidDataSourceBuilder.create().build(); } /** * 配置一平面同步pgsql数据源 * * @return 数据源对象 */ @Bean(name = "ypm-sync") @ConfigurationProperties(prefix = "spring.datasource.ypm-sync") @ConditionalOnProperty(prefix = "spring.datasource.ypm-sync", name = "url") public DataSource pgsqlYpmSyncSource() { return DruidDataSourceBuilder.create().build(); } /** * 配置自动化新一代达梦7数据源 * * @return 数据源对象 */ @Bean(name = "auto-dm") @ConfigurationProperties(prefix = "spring.datasource.auto-dm") @ConditionalOnProperty(prefix = "spring.datasource.auto-dm", name = "url") public DataSource autoDmSource() { return DruidDataSourceBuilder.create().build(); } /** * 配置自动化现货处达梦8 * * @return 数据源对象 */ @Bean(name = "ddc-dm") @ConfigurationProperties(prefix = "spring.datasource.ddc-dm") @ConditionalOnProperty(prefix = "spring.datasource.ddc-dm", name = "url") public DataSource ddcDmSource() { return DruidDataSourceBuilder.create().build(); } /** * 数据源配置 * * @param elss 数据源elss * @param envs 数据源envs * @param ypmSync 可视化ypm同步库 * @param autoDm 自动化达梦数据库 * @param ddcDm 调度出达梦数据库 * @param elssCentrally 统调弃电系统数据库 * @return 动态数据源切换对象。 */ @Bean @Primary public DataSource dataSource(@Qualifier("elss") DataSource elss, @Autowired(required = false) @Qualifier("envs") DataSource envs, @Autowired(required = false) @Qualifier("ypm-sync") DataSource ypmSync, @Autowired(required = false) @Qualifier("auto-dm") DataSource autoDm, @Autowired(required = false) @Qualifier("ddc-dm") DataSource ddcDm, @Autowired(required = false) @Qualifier("elss_centrally") DataSource elssCentrally) { Map<Object, Object> dsMap = new HashMap<>(16); dsMap.put("elss", elss); if (envs != null) { dsMap.put("envs", envs); } if (ypmSync != null) { dsMap.put("ypm-sync", ypmSync); } if (autoDm != null) { dsMap.put("auto-dm", autoDm); } if (ddcDm != null) { dsMap.put("ddc-dm", ddcDm); } if (elssCentrally != null) { dsMap.put("elss-centrally", elssCentrally); } return new DynamicDataSource(elss, dsMap); } }

مشاركة هذا السؤال والجواب