{"id":1922,"date":"2023-04-01T09:46:13","date_gmt":"2023-04-01T01:46:13","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=1922"},"modified":"2023-04-22T08:51:37","modified_gmt":"2023-04-22T00:51:37","slug":"spring-boot-integrates-nacos-to-dynamically-refresh-data-sources","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/04\/01\/spring-boot-integrates-nacos-to-dynamically-refresh-data-sources\/","title":{"rendered":"Spring Boot\u96c6\u6210Nacos\u52a8\u6001\u5237\u65b0\u6570\u636e\u6e90"},"content":{"rendered":"<h3>\u524d\u8a00<\/h3>\n<p>\u56e0\u4e3a\u9879\u76ee\u9700\u8981\uff0c\u9700\u8981\u5728\u9879\u76ee\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u80fd\u591f\u52a8\u6001\u4fee\u6539\u6570\u636e\u6e90\uff08\u5373\uff1a\u6570\u636e\u6e90\u7684\u70ed\u66f4\u65b0\uff09\u3002\u8fd9\u91cc\u4ee5<code>com.alibaba.druid.pool.DruidDataSource<\/code>\u6570\u636e\u6e90\u4e3a\u4f8b<\/p>\n<h3>\u7b2c\u4e00\u6b65\uff1a\u91cd\u5199DruidAbstractDataSource\u7c7b<\/h3>\n<p>\u8fd9\u91cc\u4e3a\u4ec0\u4e48\u8981\u91cd\u5199\u8fd9\u4e2a\u7c7b\uff1a\u56e0\u4e3aDruidDataSource\u6570\u636e\u6e90\u5728\u521d\u59cb\u5316\u540e\uff0c\u5c31\u4e0d\u5141\u8bb8\u518d\u91cd\u65b0\u8bbe\u7f6e\u6570\u636e\u5e93\u7684url\u548cuserName<\/p>\n<p><!-- more --><\/p>\n<pre><code class=\"language-java\">package com.alibaba.druid.pool;\n...\n\npublic abstract class DruidAbstractDataSource extends WrapperAdapter implements DruidAbstractDataSourceMBean, DataSource, DataSourceProxy, Serializable {\n\n    ...\n\n    public void setUrl(String jdbcUrl) {\n        if (StringUtils.equals(this.jdbcUrl, jdbcUrl)) {\n            return;\n        }\n        \/\/ \u91cd\u5199\u7684\u65f6\u5019\uff0c\u9700\u8981\u5c06\u8fd9\u4e2a\u5224\u65ad\u6ce8\u91ca\u6389\uff0c\u5426\u5219\u4f1a\u62a5\u9519\n        \/\/ if (inited) {\n        \/\/     throw new UnsupportedOperationException();\n        \/\/ }\n\n        if (jdbcUrl != null) {\n            jdbcUrl = jdbcUrl.trim();\n        }\n\n        this.jdbcUrl = jdbcUrl;\n\n        \/\/ if (jdbcUrl.startsWith(ConfigFilter.URL_PREFIX)) {\n        \/\/ this.filters.add(new ConfigFilter());\n        \/\/ }\n    }\n\n    public void setUsername(String username) {\n        if (StringUtils.equals(this.username, username)) {\n            return;\n        }\n        \/\/ \u91cd\u5199\u7684\u65f6\u5019\uff0c\u9700\u8981\u5c06\u8fd9\u4e2a\u5224\u65ad\u6ce8\u91ca\u6389\uff0c\u5426\u5219\u4f1a\u62a5\u9519\n        \/\/ if (inited) {\n        \/\/     throw new UnsupportedOperationException();\n        \/\/ }\n\n        this.username = username;\n    }\n}<\/code><\/pre>\n<p>\u91cd\u5199\u7684\u65f6\u5019\u5305\u8def\u5f84\u4e0d\u80fd\u53d8\uff0c\u53ea\u6709\u8fd9\u6837\u7c7b\u52a0\u8f7d\u7684\u65f6\u5019\u624d\u4f1a\u4f18\u5148\u52a0\u8f7d\u91cd\u5199\u540e\u7684\u7c7b<\/p>\n<h3>\u7b2c\u4e8c\u6b65\uff1a\u914d\u7f6e\u52a8\u6001\u83b7\u53d6Nacos\u914d\u7f6e\u4fe1\u606f<\/h3>\n<p>DruidConfiguration.java<\/p>\n<pre><code class=\"language-java\">import com.alibaba.druid.pool.DruidDataSource;\nimport lombok.Data;\nimport lombok.extern.slf4j.Slf4j;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.cloud.context.config.annotation.RefreshScope;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\n\n\/**\n * \u63cf\u8ff0\uff1a\u5982\u679c\u4e0d\u4f7f\u7528\u4ee3\u7801\u624b\u52a8\u521d\u59cb\u5316DataSource\u7684\u8bdd\uff0c\u76d1\u63a7\u754c\u9762\u7684SQL\u76d1\u63a7\u4f1a\u6ca1\u6709\u6570\u636e\n *\/\n@Slf4j\n@Configuration\n@RefreshScope\n@Data\npublic class DruidConfiguration {\n    @Value(&quot;${spring.datasource.url}&quot;)\n    private String dbUrl;\n\n    @Value(&quot;${spring.datasource.username}&quot;)\n    private String username;\n\n    @Value(&quot;${spring.datasource.password}&quot;)\n    private String password;\n\n    @Value(&quot;${spring.datasource.driver-class-name}&quot;)\n    private String driverClassName;\n\n    \/\/ @Value(&quot;${spring.datasource.initialSize}&quot;)\n    \/\/ private int initialSize;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.minIdle}&quot;)\n    \/\/ private int minIdle;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.maxActive}&quot;)\n    \/\/ private int maxActive;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.maxWait}&quot;)\n    \/\/ private int maxWait;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.timeBetweenEvictionRunsMillis}&quot;)\n    \/\/ private int timeBetweenEvictionRunsMillis;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.minEvictableIdleTimeMillis}&quot;)\n    \/\/ private int minEvictableIdleTimeMillis;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.validationQuery}&quot;)\n    \/\/ private String validationQuery;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.testWhileIdle}&quot;)\n    \/\/ private boolean testWhileIdle;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.testOnBorrow}&quot;)\n    \/\/ private boolean testOnBorrow;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.testOnReturn}&quot;)\n    \/\/ private boolean testOnReturn;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.poolPreparedStatements}&quot;)\n    \/\/ private boolean poolPreparedStatements;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.maxPoolPreparedStatementPerConnectionSize}&quot;)\n    \/\/ private int maxPoolPreparedStatementPerConnectionSize;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.filters}&quot;)\n    \/\/ private String filters;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.connectionProperties}&quot;)\n    \/\/ private String connectionProperties;\n    \/\/\n    \/\/ @Value(&quot;${spring.datasource.useGlobalDataSourceStat}&quot;)\n    \/\/ private boolean useGlobalDataSourceStat;\n\n    @Bean\n    @RefreshScope\n    public DruidDataSource dataSource() {\n        DruidDataSource datasource = new DruidDataSource();\n        datasource.setUrl(this.dbUrl);\n        datasource.setUsername(username);\n        datasource.setPassword(password);\n        datasource.setDriverClassName(driverClassName);\n\n        \/\/configuration\n        \/\/ datasource.setInitialSize(initialSize);\n        \/\/ datasource.setMinIdle(minIdle);\n        \/\/ datasource.setMaxActive(maxActive);\n        \/\/ datasource.setMaxWait(maxWait);\n        \/\/ datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);\n        \/\/ datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);\n        \/\/ datasource.setValidationQuery(validationQuery);\n        \/\/ datasource.setTestWhileIdle(testWhileIdle);\n        \/\/ datasource.setTestOnBorrow(testOnBorrow);\n        \/\/ datasource.setTestOnReturn(testOnReturn);\n        \/\/ datasource.setPoolPreparedStatements(poolPreparedStatements);\n        \/\/ datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);\n        \/\/ datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);\n        \/\/ try {\n        \/\/     datasource.setFilters(filters);\n        \/\/ } catch (SQLException e) {\n        \/\/     log.error(&quot;druid configuration initialization filter: &quot; + e);\n        \/\/ }\n        \/\/ datasource.setConnectionProperties(connectionProperties);\n        return datasource;\n    }\n}<\/code><\/pre>\n<p>\u8fd9\u91cc\u8981\u6ce8\u610f\u589e\u52a0<code>@RefreshScope<\/code>\u6ce8\u89e3<\/p>\n<h3>\u7b2c\u4e09\u6b65\uff1a\u624b\u52a8\u5237\u65b0\u6570\u636e\u6e90<\/h3>\n<pre><code class=\"language-java\">@GetMapping(&quot;\/refresh&quot;)\npublic String refresh() throws SQLException\n{\n    DruidDataSource master = SpringUtils.getBean(&quot;dataSource&quot;);\n    master.setUrl(druidConfiguration.getDbUrl());\n    master.setUsername(druidConfiguration.getUsername());\n    master.setPassword(druidConfiguration.getPassword());\n    master.setDriverClassName(druidConfiguration.getDriverClassName());\n    master.restart();\n    return userName + &quot;&lt;&gt;&quot; + jdbcUrl + &quot;----------&quot; + druidConfiguration.getDbUrl();\n}<\/code><\/pre>\n<p>SpringUtils.java<\/p>\n<pre><code class=\"language-java\">import org.springframework.beans.BeansException;\nimport org.springframework.context.ApplicationContext;\nimport org.springframework.context.ApplicationContextAware;\nimport org.springframework.stereotype.Component;\n\nimport java.util.Map;\n\n@Component\npublic class SpringUtils implements ApplicationContextAware {\n\n    private static ApplicationContext applicationContext;\n\n    @Override\n    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {\n        SpringUtils.applicationContext = applicationContext;\n    }\n\n    public static &lt;T&gt; T getBean(String beanName) {\n        if (applicationContext.containsBean(beanName)) {\n            return (T) applicationContext.getBean(beanName);\n        } else {\n            return null;\n        }\n    }\n\n    public static &lt;T&gt; Map&lt;String, T&gt; getBeansOfType(Class&lt;T&gt; baseType) {\n        return applicationContext.getBeansOfType(baseType);\n    }\n\n    public static ApplicationContext getApplicationContext() {\n        return applicationContext;\n    }\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u524d\u8a00 \u56e0\u4e3a\u9879\u76ee\u9700\u8981\uff0c\u9700\u8981\u5728\u9879\u76ee\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u80fd\u591f\u52a8\u6001\u4fee\u6539\u6570\u636e\u6e90\uff08\u5373\uff1a\u6570\u636e\u6e90\u7684\u70ed\u66f4\u65b0\uff09\u3002\u8fd9\u91cc\u4ee5com.alibaba [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,41],"tags":[],"class_list":["post-1922","post","type-post","status-publish","format-standard","hentry","category-nacos","category-spring-boot"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1922","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=1922"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/1922\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=1922"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=1922"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=1922"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}