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

您所在的位置:网站首页 nacos数据源 java spring cloud 使用nacos配置多数据源(druid)AbstractRoutingDataSource

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

2024-06-10 15:33| 来源: 网络整理| 查看: 265

第一步、在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 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 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 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() { ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); Map initParams = new HashMap(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() { FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(new WebStatFilter()); Map 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配置多数据源并实现自动切换



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3