栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring-boot配置多数据源(动态数据源,基于注解和切面方式)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring-boot配置多数据源(动态数据源,基于注解和切面方式)

一、自定义DB注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DS {
    
    String value();

}
二、配置properties数据源

文件名:jdbc.properties

# slave-authserver
spring.datasource.slave.authserver.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slave.authserver.jdbc-url=jdbc:mysql://localhost:3306/smart-authserver?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
spring.datasource.slave.authserver.username=root
spring.datasource.slave.authserver.password=123456

# slave-data
spring.datasource.slave.data.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slave.data.jdbc-url=jdbc:mysql://localhost:3306/smart-data?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
spring.datasource.slave.data.username=root
spring.datasource.slave.data.password=123456

# slave-kpi
spring.datasource.slave.kpi.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slave.kpi.jdbc-url=jdbc:mysql://localhost:3306/smart-kpi?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
spring.datasource.slave.kpi.username=root
spring.datasource.slave.kpi.password=123456

# slave-logistics
spring.datasource.slave.logistics.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slave.logistics.jdbc-url=jdbc:mysql://localhost:3306/smart-logistics?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
spring.datasource.slave.logistics.username=root
spring.datasource.slave.logistics.password=123456
三、设置各数据源常量
public interface DataSourceConstants {

    
    String DS_KEY_SLAVE_DATA = "DS_KEY_SLAVE_DATA";

    
    String DS_KEY_SLAVE_AUTH = "DS_KEY_SLAVE_AUTH";

    
    String DS_KEY_SLAVE_LOGISTICS = "DS_KEY_SLAVE_LOGISTICS";

    
    String DS_KEY_SLAVE_KPI = "DS_KEY_SLAVE_KPI";

}
四、Spring配置多数据源
import com.jnx.smart.authserver.db.DynamicDataSource;
import com.jnx.smart.base.constant.DataSourceConstants;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
@PropertySource("classpath:jdbc.properties")
@MapperScan(basePackages = {
        "com.jnx.smart.authserver.business.repository.dao",
        "com.jnx.smart.data.business.repository.dao",
        "com.jnx.smart.assess.business.repository.dao",
        "com.jnx.smart.logistics.business.repository.dao"})
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class DynamicDataSourceConfig {

    @Bean
    @Primary
    public DataSource dynamicDataSource() {
        Map dataSourceMap = new HashMap<>(2);
        dataSourceMap.put(DataSourceConstants.DS_KEY_SLAVE_AUTH, slaveDataSourceAuth());
        dataSourceMap.put(DataSourceConstants.DS_KEY_SLAVE_DATA, slaveDataSourceData());
        dataSourceMap.put(DataSourceConstants.DS_KEY_SLAVE_KPI, slaveDataSourceKpi());
        dataSourceMap.put(DataSourceConstants.DS_KEY_SLAVE_LOGISTICS, slaveDataSourceLogistics());
        //设置动态数据源
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(dataSourceMap);
        //单点登录系统,设置默认数据源为点点登陆数据库
        dynamicDataSource.setDefaultTargetDataSource(slaveDataSourceAuth());

        return dynamicDataSource;
    }

    
    @Bean("DS_KEY_SLAVE_AUTH")
    @ConfigurationProperties(prefix = "spring.datasource.slave.authserver")
    public DataSource slaveDataSourceAuth() {
        return DataSourceBuilder.create().build();
    }

    
    @Bean("DS_KEY_SLAVE_DATA")
    @ConfigurationProperties(prefix = "spring.datasource.slave.data")
    public DataSource slaveDataSourceData() {
        return DataSourceBuilder.create().build();
    }

    
    @Bean("DS_KEY_SLAVE_KPI")
    @ConfigurationProperties(prefix = "spring.datasource.slave.kpi")
    public DataSource slaveDataSourceKpi() {
        return DataSourceBuilder.create().build();
    }

    
    @Bean("DS_KEY_SLAVE_LOGISTICS")
    @ConfigurationProperties(prefix = "spring.datasource.slave.logistics")
    public DataSource slaveDataSourceLogistics() {
        return DataSourceBuilder.create().build();
    }
}
五、数据源的上下文配置

数据源上下文设置

import com.jnx.smart.base.constant.DataSourceConstants;


public class DynamicDataSourceContextHolder {

    
    private static final ThreadLocal DATASOURCE_CONTEXT_KEY_HOLDER = new ThreadLocal<>();

    
    public static void setContextKey(String key) {
        DATASOURCE_CONTEXT_KEY_HOLDER.set(key);
    }

    
    public static String getContextKey() {
        String key = DATASOURCE_CONTEXT_KEY_HOLDER.get();
        return key == null ? DataSourceConstants.DS_KEY_SLAVE_AUTH : key;
    }

    
    public static void removeContextKey() {
        DATASOURCE_CONTEXT_KEY_HOLDER.remove();
    }
}

获取上下文的数据源

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;


public class DynamicDataSource extends AbstractRoutingDataSource {
    
    @Override
    protected Object determineCurrentLookupKey() {
        // 当设置数据源 key 到上下文,则从上下文中得到此数据源 key
        return DynamicDataSourceContextHolder.getContextKey();
    }
    
}

AOP切面处理

import com.jnx.smart.base.annotation.DS;
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.stereotype.Component;

import java.util.Objects;


@Aspect
@Component
public class DynamicDataSourceAspect {

    @Pointcut("@annotation(com.jnx.smart.base.annotation.DS)")
    public void dataSourcePointCut() {

    }

    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        String dsKey = getDSAnnotation(joinPoint).value();
        DynamicDataSourceContextHolder.setContextKey(dsKey);
        try {
            return joinPoint.proceed();
        } finally {
            DynamicDataSourceContextHolder.removeContextKey();
        }
    }

    
    private DS getDSAnnotation(ProceedingJoinPoint joinPoint) {
        Class targetClass = joinPoint.getTarget().getClass();
        DS dsAnnotation = targetClass.getAnnotation(DS.class);
        // 先判断类的注解,再判断方法注解
        if (Objects.nonNull(dsAnnotation)) {
            return dsAnnotation;
        } else {
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            return methodSignature.getMethod().getAnnotation(DS.class);
        }
    }

}
六、使用

在完成以上配置后,直接在需要使用的service方法上,打上注解任选一个需要的数据源@DB(value=DataSourceConstants.DS_KEY_SLAVE_DATA)
,程序执行时就会从指定的数据源进行操作。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/873854.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号