一、引入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. 任务日历关联(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 有时候吧,一件大事是由N件小事组成的,而这N件小事当中,不是每件事都可以在周末停下来的,当然也不是所有的事都必须在周末完成 ...

  2. PLSQL Developer 13安装教程

    1:双击安装包进行安装.点击"next".2:点击"w accept the termis..."同意条款,并点击"next",进行下一步. ...

  3. c++模板类的使用,编译的问题

    1,模板类编译的问题 前两天在写代码时,把模板类的声明和分开放在两个文件中了,类似于下面这样: stack.hpp: #ifndef _STACK_HPP #define _STACK_HPP tem ...

  4. Hooks中的useState

    Hooks中的useState React的数据是自顶向下单向流动的,即从父组件到子组件中,组件的数据存储在props和state中,实际上在任何应用中,数据都是必不可少的,我们需要直接的改变页面上一 ...

  5. 两阶提交、三阶提交、TCC框架

    首先介绍一下分布式事务,分布式事务是指会涉及到操作多个数据库的事务.其实就是将对同一库事务的概念扩大到了对多个库的事务.目的是为了保证分布式系统中的数据一致性.分布式事务处理的关键是必须有一种方法可以 ...

  6. Xftp设置指定记事本(notepad++)打开文件

    右键

  7. 注解版mybatis动态语句将空字符串转换为null

    Convert.java import java.util.Map; import java.util.Objects; /** * * @ClassName: Convert * @Descript ...

  8. 『与善仁』Appium基础 — 29、获取toast信息

    目录 1.toast介绍 2.toast定位 3.示例 4.封装toast判断 1.toast介绍 Android中的toast是一种简易的消息提示框,toast提示框不能被用户点击,会根据所设置的显 ...

  9. 【LeetCode】448. Find All Numbers Disappeared in an Array 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 方法一:暴力求解 方法二:原地变负做标记 方法三:使用set ...

  10. 【LeetCode】862. Shortest Subarray with Sum at Least K 解题报告(C++)

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