文章目录

前言

因为项目需要,需要在项目运行过程中能够动态修改数据源(即:数据源的热更新)。这里以​​com.alibaba.druid.pool.DruidDataSource​​数据源为例

第一步:重写DruidAbstractDataSource类

这里为什么要重写这个类:因为​​DruidDataSource​​数据源在初始化后,就不允许再重新设置数据库的url和userName

public void setUrl(String jdbcUrl) {
if (StringUtils.equals(this.jdbcUrl, jdbcUrl)) {
return;
}
// 重写的时候,需要将这个判断注释掉,否则会报错
// if (inited) {
// throw new UnsupportedOperationException();
// }

if (jdbcUrl != null) {
jdbcUrl = jdbcUrl.trim();
}

this.jdbcUrl = jdbcUrl;

// if (jdbcUrl.startsWith(ConfigFilter.URL_PREFIX)) {
// this.filters.add(new ConfigFilter());
// }
}

public void setUsername(String username) {
if (StringUtils.equals(this.username, username)) {
return;
}
// 重写的时候,需要将这个判断注释掉,否则会报错
// if (inited) {
// throw new UnsupportedOperationException();
// }

this.username = username;
}

重写的时候包路径不能变,只有这样类加载的时候才会优先加载重写后的类
然后就是最重要的一步(这个视Druid版本来修改)重申一下我用的Druid版本为1.1.10

重写​​com.alibaba.druid.pool.DruidAbstractDataSource​​类

由于Druid只允许初始化一次,所以只能修改他的源码,而版本不同会导致该类并不相同,在修改源码时必须尤为注意!!!!!!

Nacos配置中心动态刷新数据源_spring boot

第二步:配置动态获取nacos配置信息

package com.easyshop.config;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
*
* 描述:如果不使用代码手动初始化DataSource的话
*/
@Slf4j
@Configuration
@RefreshScope
@Data
public class DruidConfiguration
{
@Value("${spring.datasource.url}")
private String dbUrl;

@Value("${spring.datasource.username}")
private String username;

@Value("${spring.datasource.password}")
private String password;

@Value("${spring.datasource.driver-class-name}")
private String driverClassName;

// @Value("${spring.datasource.initialSize}")
// private int initialSize;
//
// @Value("${spring.datasource.minIdle}")
// private int minIdle;
//
// @Value("${spring.datasource.maxActive}")
// private int maxActive;
//
// @Value("${spring.datasource.maxWait}")
// private int maxWait;
//
// @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
// private int timeBetweenEvictionRunsMillis;
//
// @Value("${spring.datasource.minEvictableIdleTimeMillis}")
// private int minEvictableIdleTimeMillis;
//
// @Value("${spring.datasource.validationQuery}")
// private String validationQuery;
//
// @Value("${spring.datasource.testWhileIdle}")
// private boolean testWhileIdle;
//
// @Value("${spring.datasource.testOnBorrow}")
// private boolean testOnBorrow;
//
// @Value("${spring.datasource.testOnReturn}")
// private boolean testOnReturn;
//
// @Value("${spring.datasource.poolPreparedStatements}")
// private boolean poolPreparedStatements;
//
// @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
// private int maxPoolPreparedStatementPerConnectionSize;
//
// @Value("${spring.datasource.filters}")
// private String filters;
//
// @Value("${spring.datasource.connectionProperties}")
// private String connectionProperties;
//
// @Value("${spring.datasource.useGlobalDataSourceStat}")
// private boolean useGlobalDataSourceStat;

@Bean
@RefreshScope
public DruidDataSource dataSource()
{
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(this.dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);

//configuration
// datasource.setInitialSize(initialSize);
// datasource.setMinIdle(minIdle);
// datasource.setMaxActive(maxActive);
// datasource.setMaxWait(maxWait);
// datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// datasource.setValidationQuery(validationQuery);
// datasource.setTestWhileIdle(testWhileIdle);
// datasource.setTestOnBorrow(testOnBorrow);
// datasource.setTestOnReturn(testOnReturn);
// datasource.setPoolPreparedStatements(poolPreparedStatements);
// datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
// datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);
// try
// {
// datasource.setFilters(filters);
// }
// catch (SQLException e)
// {
// log.error("druid configuration initialization filter: " + e);
// }
// datasource.setConnectionProperties(connectionProperties);
return datasource;
}
}

这里要注意增加​​@RefreshScope​​注解

第三步:手动刷新数据源

@Autowired
private DruidConfiguration druidConfiguration;

@GetMapping("/refresh")
public String refresh() throws SQLException {
DruidDataSource master = SpringUtils.getBean("dataSource");
master.setUrl(druidConfiguration.getDbUrl());
master.setUsername(druidConfiguration.getUsername());
master.setPassword(druidConfiguration.getPassword());
master.setDriverClassName(druidConfiguration.getDriverClassName());
master.restart();
return druidConfiguration.getDbUrl();
}

到此这篇关于SpringBoot集成nacos动态刷新数据源的实现示例的文章就介绍到这了