Springboot 实现前台动态配置数据源 (修改数据源之后自动重启)

1.将 db.properties 存放在classpath路径;

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ceshi?useUnicode=true&characterEncoding=utf8
username=root
password=root

2.使用Bean的方式配置 dataSource

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.shulipeng.config;
 
import com.alibaba.druid.pool.DruidDataSource;
import com.shulipeng.AutocodeApplication;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
 
import javax.sql.DataSource;
import java.sql.SQLException;
 
/**
 * @author shulipeng
 * @Description:
 * @date 2018/4/2
 */
@Configuration
public class DataSourceConfig {
 
    private static Logger logger = LoggerFactory.getLogger(DataSourceConfig.class);
 
    //数据库类型
    private String dbType;
 
    @Bean(name = "dataSource")
    public DruidDataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        try {
            PropertiesConfiguration properties = new PropertiesConfiguration("db.properties");
            String driverClassName = properties.getString("driverClassName");
            dataSource.setDriverClassName(driverClassName);
            dataSource.setUrl(properties.getString("url"));
            dataSource.setUsername(properties.getString("username"));
            dataSource.setPassword(properties.getString("password"));
 
            //判断数据库类型
            if(driverClassName.contains(Constant.DB_TYPE_MYSQL)){
                this.setDbType(Constant.DB_TYPE_MYSQL);
            }else if(driverClassName.contains(Constant.DB_TYPE_ORACLE)){
                this.setDbType(Constant.DB_TYPE_ORACLE);
            }
 
        } catch (ConfigurationException e) {
            logger.error("获取数据库配置文件失败" + e);
        }
 
        return dataSource;
    }
 
    /**
     * 动态修改数据库链接
     */
    public void changeDataSource () {
        Thread restartThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    AutocodeApplication.restart();
                } catch (InterruptedException ignored) {
                }
            }
        });
        restartThread.setDaemon(false);
        restartThread.start();
    }
 
    public String getDbType() {
        return dbType;
    }
 
    public void setDbType(String dbType){
        this.dbType = dbType;
    }
}

3.定义一个前台改变数据库配置文件并且重启的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
   * 动态修改数据库地址,并且重新启动应用
   * @param dbMap
   * @return
   */
  @PostMapping("/db/update")
  @ResponseBody
  R changeDB(@RequestParam Map<String,Object> dbMap){
      try {
          PropertiesConfiguration conf = new PropertiesConfiguration("db.properties");
          conf.setProperty("driverClassName",dbMap.get("driverClassName"));
          conf.setProperty("url",dbMap.get("url"));
          conf.setProperty("username",dbMap.get("username"));
          conf.setProperty("password",dbMap.get("password"));
          conf.save();
          dataSourceConfig.changeDataSource();
      } catch (ConfigurationException e) {
          logger.error("获取数据库配置文件失败:" + e);
          return R.error("保存配置文件时出错" + e);
      }
      return  R.ok();
  }

4.修改Application.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.shulipeng;
 
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ConfigurableApplicationContext;
 
@ServletComponentScan
@MapperScan("com.shulipeng.dao")
@SpringBootApplication
public class AutocodeApplication {
 
    private static String[] args;
    private static ConfigurableApplicationContext context;
 
    public static void main(String[] args) {
        AutocodeApplication.args = args;
        AutocodeApplication.context = SpringApplication.run(AutocodeApplication.class, args);
    }
 
    public static void restart() {
        context.close();
        AutocodeApplication.context = SpringApplication.run(AutocodeApplication.class, args);
 
    }
}

 

5.就这样就可以了,只是每次修改数据源就会重启服务。Spring cloud 有一个注解 RefreshScope 好像可以实现不用重启项目就可以动态修改数据源的方式,但是没有接触过,目前这种正好就是我需要的,所以就记录下来了  

  

  

  

posted @   君子如珩~  阅读(13976)  评论(8编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示