一、引入maven依赖,使用 starter 与原生 druid 依赖配置有所不同

        <dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>

二、配置数据源

spring:
datasource:
druid:
filter:
stat: #开启sql监控
enabled: true
wall:
enabled: true
slf4j:
enabled: true
DB1:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:sqlserver://127.0.0.1:1487;DatabaseName=CN2018
username: root
password: 12345
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
# 连接池的配置信息
initial-size: 5
min-idle: 5
maxActive: 20
maxWait: 60000 # 配置获取连接等待超时的时间
timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒
# validationQuery: SELECT 1 FROM DUAL # mysql数据库
validationQuery: SELECT 1 # sqlserver 数据库
poolPreparedStatements: true # 打开PSCache,并且指定每个连接上PSCache的大小
maxPoolPreparedStatementPerConnectionSize: 20
DB2:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:sqlserver://127.0.0.1:1488;DatabaseName=DB2022
username: root
password: 123456
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
# 连接池的配置信息
initial-size: 1
min-idle: 1
maxActive: 5
maxWait: 60000 # 配置获取连接等待超时的时间
timeBetweenEvictionRunsMillis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最小生存的时间,单位是毫秒
# validationQuery: SELECT 1 FROM DUAL # mysql数据库
validationQuery: SELECT 1 # sqlServer 数据库
poolPreparedStatements: true # 打开PSCache,并且指定每个连接上PSCache的大小
maxPoolPreparedStatementPerConnectionSize: 20

三、创建配置类

//记录数据库名
public interface ContextConst {
enum DataSourceType{
DB1,DB2
}
}
//数据源持有类
@Slf4j
public class DataSourceContextHolder {
/**
* CONTEXT_HOLDER代表一个可以存放String类型的ThreadLocal对象,
* 此时任何一个线程可以并发访问这个变量,
* 对它进行写入、读取操作,都是线程安全的。
* 比如一个线程通过CONTEXT_HOLDER.set(“aaaa”);将数据写入ThreadLocal中,
* 在任何一个地方,都可以通过CONTEXT_HOLDER.get();将值获取出来。
* 这里写入的就是数据库名,
*/
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>(); public static void setDataSource(String dbType){
CONTEXT_HOLDER.set(dbType);
} public static String getDataSource(){
return CONTEXT_HOLDER.get();
} public static void clearDataSource(){
CONTEXT_HOLDER.remove();
}
}
//数据源路由实现类
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
* @Description:数据源路由实现类 AbstractRoutingDataSource(每执行一次数据库 , 动态获取DataSource)
*/
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
}
//自定义切换数据源注解
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetDateSouce {
ContextConst.DataSourceType value() default ContextConst.DataSourceType.DB1;
}
//AOP动态数据源通知
@Component
@Aspect
@Order(-1) //保证在@Transactional之前执行,必须加上,不然无法分辨是哪个数据源在执行事务
@Slf4j
public class DynamicDataSourceAspect { @Before("execution(* com.blaze.pboc.service..*.*(..))")
public void before(JoinPoint point) {
try {
TargetDateSouce annotationOfClass = point.getTarget().getClass().getAnnotation(TargetDateSouce.class);
String methodName = point.getSignature().getName();
Class[] parameterTypes = ((MethodSignature) point.getSignature()).getParameterTypes();
Method method = point.getTarget().getClass().getMethod(methodName, parameterTypes);
TargetDateSouce methodAnnotation = method.getAnnotation(TargetDateSouce.class);
methodAnnotation = methodAnnotation == null ? annotationOfClass : methodAnnotation;
ContextConst.DataSourceType dataSourceType = methodAnnotation != null && methodAnnotation.value() != null ? methodAnnotation.value() : ContextConst.DataSourceType.DB1;
DataSourceContextHolder.setDataSource(dataSourceType.name());
} catch (NoSuchMethodException e) {
log.error("error", e);
}
} @After("execution(* com.blaze.pboc.service..*.*(..))")
public void after(JoinPoint point) {
DataSourceContextHolder.clearDataSource();
}
}
//动态数据源配置类
@SpringBootConfiguration
public class DruidDataSourceConfig { @Bean
@ConfigurationProperties(prefix = "spring.datasource.druid.db1")
public DruidDataSource masterDataSource() {
return DruidDataSourceBuilder.create().build();
} @Bean
@ConfigurationProperties(prefix = "spring.datasource.druid.db2")
public DruidDataSource clusterDataSource() {
DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
return druidDataSource;
} @Primary
@Bean
public DataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
//配置默认数据源
dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
//配置多数据源这里的key一定要是string类型,枚举类型并不支持,所以用到枚举中name()方法转成string,或者用toString方法。
HashMap<Object, Object> dataSourceMap = new HashMap();
dataSourceMap.put(ContextConst.DataSourceType.DB1.name(), masterDataSource());
dataSourceMap.put(ContextConst.DataSourceType.DB2.name(), clusterDataSource());
dynamicDataSource.setTargetDataSources(dataSourceMap);
return dynamicDataSource;
} // 配置@Transactional注解事务
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dynamicDataSource());
} //配置 Druid 监控管理后台的Servlet;
//内置 Servlet 容器时没有web.xml文件,所以使用 Spring Boot 的注册 Servlet 方式
@Bean
public ServletRegistrationBean registrationBean() {
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
Map<String, String> initParameters = new HashMap<>();
initParameters.put("loginUsername", "admin");
initParameters.put("loginPassword", "12345");
bean.setInitParameters(initParameters);
return bean;
} //去除Druid监控页面的广告
@Bean
public FilterRegistrationBean removeDruidAdFilter() throws IOException {
String text = Utils.readFromResource("support/http/resources/js/common.js");
final String newJs = text.replace("this.buildFooter();", "");
// 新建一个过滤器注册器对象
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
// 注册common.js文件的过滤器
registration.addUrlPatterns("/druid/js/common.js");
// 添加一个匿名的过滤器对象,并把改造过的common.js文件内容写入到浏览器
registration.setFilter((servletRequest, servletResponse, filterChain) -> {
// 重置缓冲区,响应头不会被重置
servletResponse.resetBuffer();
// 把改造过的common.js文件内容写入到浏览器
servletResponse.getWriter().write(newJs);
});
return registration;
} }

四、测试,常用的数据源配置db1,无需添加注解

五、登陆 web 监控端

http://127.0.0.1:9000/api/druid/login.html

Springboot+Druid 动态数据源配置监控的更多相关文章

  1. Druid动态数据源配置

    上文已经讲了单个数据源的Druid的配置(http://www.cnblogs.com/nbfujx/p/7686634.html) Druid动态数据源配置 主要是继承AbstractRouting ...

  2. Spring Boot2.x 动态数据源配置

    原文链接: Spring Boot2.x 动态数据源配置 基于 Spring Boot 2.x.Spring Data JPA.druid.mysql 的动态数据源配置Demo,适合用于数据库的读写分 ...

  3. 基于springboot的多数据源配置

    发布时间:2018-12-11   技术:springboot1.5.1 + maven3.0.1+ mybatis-plus-boot-starter2.3.1 + dynamic-datasour ...

  4. springboot+ibatis 多数据源配置

    这个是boot基本版本包,因为我用的打包方式是war所以去除掉了boot内置的tomcat,但是为了方便测试又引入了内置tomcat,只要添加<scope>provided</sco ...

  5. (七)spring+druid多数据源配置

    druid多数据源配置 一.druid简介 Druid首先是一个数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser. ...

  6. springboot+druid连接池及监控配置

    1. 问题描述 阿里巴巴的数据库连接池Druid在效率与稳定性都很高,被很多开发团队使用,并且自带的Druid监控也很好用,本章简单介绍下springboot+druid配置连接池及监控. 2. 解决 ...

  7. spring boot +mybatis+druid 多数据源配置

    因为我的工程需要在两个数据库中操作数据,所以要配置两个数据库,我这里没有数据源没有什么主从之分,只是配合多数据源必须要指定一个主数据源,所以我就把 操作相对要对的那个数据库设置为主数据(dataBas ...

  8. Mybatis+Druid多数据源配置

    在日常开发中我们可能会用到多数据源开发,什么是多数据源? 简单来讲的话,就是一个项目连接多个数据库.当然只是可能会用到,我暂时没见过应用场景,但是还是了解学习一下 此项目可以基于上一个简单集成项目进行 ...

  9. SpringBoot 的多数据源配置

    最近在项目开发中,需要为一个使用 MySQL 数据库的 SpringBoot 项目,新添加一个 PLSQL 数据库数据源,那么就需要进行 SpringBoot 的多数据源开发.代码很简单,下面是实现的 ...

随机推荐

  1. SWPUCTF_2019_p1KkHeap(tcache_entry)

    花了半天的时间去理解吃透这道题目,也参考了大佬的wp (1条消息) [pwn]SWPUCTF_2019_p1KkHeap_Nothing-CSDN博客. (1条消息) swpuctf2019 p1Kk ...

  2. Vlookup大叔早已油腻(Excel函数集团)

    1.Vlookup基础用法:https://mp.weixin.qq.com/s/0JRytWlBD-KYM2jkecG2rA 2.合并字符串:https://mp.weixin.qq.com/s/9 ...

  3. 『学了就忘』Linux系统管理 — 85、工作管理相关命令

    目录 1.工作管理简介 2.如何把命令放入后台 3.后台管理命令 (1)查看后台的工作 (2)将后台暂停的工作恢复到前台执行 (3)把后台暂停的工作恢复到后台执行 4.后台命令脱离登录终端运行 1.工 ...

  4. CF729A Interview with Oleg 题解

    Content 给出一个长度为 \(n\) 字符串 \(s\),请将开头为 \(\texttt{ogo}\),后面带若干个 \(\texttt{go}\) 的子串替换成 \(\texttt{***}\ ...

  5. java 数据类型:<泛型>在方法中和在构造器中的应用

    背景: Java不允许我们把对象放在一个未知的集合中. import java.util.ArrayList; import java.util.List; /** * @ClassName Meth ...

  6. 【LeetCode】965. Univalued Binary Tree 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 BFS DFS 日期 题目地址:https://le ...

  7. Quoit Design(hdu1007)

    ---恢复内容开始--- Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Ja ...

  8. idea使用教程-安装

    [1]将安装包进行解压-->选择固态盘符 [2]发送到桌面快捷方式,生成一个快捷方式 [3]打开: 选择主题: 先进入再说,免费试用: 创建一个项目: 选择JDK: 找到jetbrains-ag ...

  9. 第九届河南理工大学算法程序设计大赛 正式赛L:最优规划(最小生成树)

    单测试点时限: 1.0 秒 内存限制: 512 MB 有很多城市之间已经建立了路径,但是有些城市之间没有路径联通.为了联通所有的城市,现在需要添加一些路径,为了节约,需要满足添加总路径是最短的. 输入 ...

  10. Codeforces 1113C: Sasha and a Bit of Relax(位运算|异或)

    time limit per test: 1 secondmemory limit per test: 256 megabytesinput: standard inputoutput: standa ...