java spring cloud 使用nacos配置多数据源(druid)AbstractRoutingDataSource

第一步、在nacos中加入

spring:
  datasource:
    master:
      url: jdbc:mysql://base-mysql:3306/XXX?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      name: master
      initialize: true
      filters: stat
    slave1:
      url: jdbc:mysql://base-mysql:3306/XXX?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      name: slave1
      initialize: true
      filters: stat

其中的的 base-mysql是配置了host 使用ip即可
这样我们就配置好了两个数据源分别为 master和slave1
之后去到spring 启动页面添加

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})

之后自定义的数据源的注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
@Target({
        ElementType.METHOD
})
public @interface MyDataSource {
    String value() default "master";
}

操作数据源

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class DynamicDataSourceSwitcher {

    static Logger logger = LoggerFactory.getLogger(DynamicDataSourceSwitcher.class);

    public static final String Mater = "master";
    public static final String Slave1 = "slave1";

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

    public static void setDataSource(String name){
        logger.info("-------- 设置数据源数据源为 :{} ", name);
        contextHolder.set(name);
    }

    public static String getDataSource(){
            if (StringUtils.isEmpty(CONTEXTHOLDER.get())) {
            setDataSource(MATER);
        }
        return contextHolder.get();
    }

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

}

多数据源bean的配置类

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
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 javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class MultipleDataSourceConfig {

    @Bean("master")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource createMasterDataSource(){
        return new DruidDataSource();
    }

    @Bean("slave1")
    @ConfigurationProperties(prefix = "spring.datasource.slave1")
    public DataSource createSlave1DataSource(){
        return new DruidDataSource();
    }

    /**
     * 设置动态数据源,通过@Primary 来确定主DataSource
     * @return
     */
    @Bean
    @Primary
    public DataSource createDynamicDataSource(@Qualifier("master") DataSource master, @Qualifier("slave1") DataSource slave1){
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        //设置默认数据源
        dynamicDataSource.setDefaultTargetDataSource(master);
        //配置多数据源
        Map<Object, Object> map = new HashMap<>();
        map.put("master",master);
        map.put("slave1",slave1);
        dynamicDataSource.setTargetDataSources(map);
        return  dynamicDataSource;
    }
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;


public class DynamicDataSource extends AbstractRoutingDataSource {

    Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);

    @Override
    protected Object determineCurrentLookupKey() {
        logger.info("------------------当前数据源 {}", DynamicDataSourceSwitcher.getDataSource());
        return DynamicDataSourceSwitcher.getDataSource();
    }
}

创建aop切面

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Order(1)
public class DynamicDataSourceAspect {
    private Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.class);

    /**
     * 切入点只对@Service注解的类上的@DataSource方法生效
     * @param myDataSource
     */
    @Pointcut(value="@within(org.springframework.stereotype.Service) && @annotation(myDataSource)" )
    public void dynamicDataSourcePointCut(MyDataSource myDataSource){}

    @Before(value = "dynamicDataSourcePointCut(myDataSource)")
    public void switchDataSource(MyDataSource myDataSource) {
        DynamicDataSourceSwitcher.setDataSource(myDataSource.value());
    }

    /**
     * 切点执行完后 切换成主数据库
     * @param myDataSource
     */
    @After(value="dynamicDataSourcePointCut(myDataSource)")
    public void after(MyDataSource myDataSource){
        DynamicDataSourceSwitcher.cleanDataSource();
    }
}

之后在service中使用即可

    @Override
    @MyDataSource(value = DynamicDataSourceSwitcher.Slave1)
    public List<Map> getAllByArticleTitleOne() {
        return articleBodysMapper.getAllByArticleTitleOne();
    }

这样就成功使用的是Slave1的数据库

之后配置监控页面


import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class DruidConfig {
    

    /**
     * 配置Druid的监控:一个管理后台的Servlet
     */
    @Bean
    public ServletRegistrationBean<StatViewServlet> statViewServlet() {
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
        Map<String, String> initParams = new HashMap<String, String>(16);
        //用户名
        initParams.put("loginUsername", "admin");
        //密码
        initParams.put("loginPassword", "123456");
        //IP白名单(没有配置或者为空,则允许所有访问)
        initParams.put("allow", "");
        //IP黑名单 (存在共同时,deny优先于allow)
        initParams.put("deny", "");
        bean.setInitParameters(initParams);


        return bean;
    }

    @Bean
    public FilterRegistrationBean<WebStatFilter> webStatFilter() {
        FilterRegistrationBean<WebStatFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new WebStatFilter());


        Map<String, String> initParams = new HashMap<>(16);
        initParams.put("exclusions", "*.js,*.css,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));


        return bean;
    }
}

上面配置的就是访问路径和账号密码之类的,
搞好之后就可以通过

服务IP地址+服务名称+/druid/login.html
http://192.168.2.112/other/druid/index.html
访问

本机ip+运行服务端口号+/druid/login.html
http://192.168.1.101:6009/druid/login.html

注意配置了spring security记得放行 - /druid/**
服务IP地址+服务名称+/druid/login.html这种方式我这边会报权限问题刷新一下自动跳转成本机ip+运行服务端口号+/druid/login.html不知道为什么,明明放行了emm

引用 完全实现 Springboot2.x + druid1.1.x配置多数据源并实现自动切换

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过在Nacos配置中心上配置两个不同的配置文件,分别对应MySQL和Oracle数据源的配置。在Spring Cloud应用中,通过使用Spring Cloud Config客户端,将这些配置文件下载到本地,并在应用程序中进行解析和使用。 以下是一个简单的示例,假设我们有两个数据源:MySQL和Oracle。我们可以在Nacos配置中心上创建两个不同的配置文件:mysql.properties和oracle.properties。示例配置如下: mysql.properties: ``` jdbc.url=jdbc:mysql://localhost:3306/mysql_db jdbc.username=mysql_user jdbc.password=mysql_password ``` oracle.properties: ``` jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl jdbc.username=oracle_user jdbc.password=oracle_password ``` 然后,在Spring Cloud应用程序中,我们可以使用以下代码来加载这些配置文件,并在应用程序中使用它们: ```java @Configuration @RefreshScope public class DataSourceConfig { @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean(name = "mysqlDataSource") @Primary public DataSource mysqlDataSource() { return DataSourceBuilder.create() .url(url) .username(username) .password(password) .driverClassName("com.mysql.jdbc.Driver") .build(); } @Bean(name = "oracleDataSource") public DataSource oracleDataSource() { return DataSourceBuilder.create() .url(url) .username(username) .password(password) .driverClassName("oracle.jdbc.driver.OracleDriver") .build(); } } ``` 在这个例子中,我们使用@Value注释来注入配置文件中的属性。然后,我们可以使用DataSourceBuilder来构建数据源对象,并将其声明为Spring Bean。通过在@Bean注释中设置名称,我们可以在应用程序中引用这些数据源对象。 需要注意的是,使用Spring Cloud Config客户端从Nacos配置中心下载配置文件的具体细节可能会有所不同,具体取决于您的应用程序和环境。但是,上述示例应该可以帮助您了解如何在Spring Cloud应用程序中使用多个数据源配置

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值