From 026262c5980522b29233afeabb2c24ec40db7c4a Mon Sep 17 00:00:00 2001 From: TaoYu <332309254@qq.com> Date: Wed, 10 May 2023 14:44:15 +0800 Subject: [PATCH] feat: creator support no global Config --- .github/FUNDING.yml | 2 +- CODE_OF_CONDUCT.md | 8 +- CONTRIBUTING.md | 4 +- README.md | 8 +- .../atomikos/AtomikosDataSourceCreator.java | 4 + .../creator/beecp/BeeCpDataSourceCreator.java | 6 +- .../creator/dbcp/Dbcp2DataSourceCreator.java | 4 + .../datasource/creator/druid/DruidConfig.java | 194 ------------------ .../creator/druid/DruidConfigUtil.java | 86 ++++++++ .../creator/druid/DruidDataSourceCreator.java | 37 +++- .../creator/druid/DruidLogConfigUtil.java | 2 +- .../creator/druid/DruidStatConfigUtil.java | 2 +- .../creator/druid/DruidWallConfigUtil.java | 2 +- .../hikaricp/HikariDataSourceCreator.java | 9 +- .../toolkit/ConfigMergeCreator.java | 5 +- .../datasource/toolkit/DsConfigUtil.java | 28 ++- dynamic-datasource-spring-boot-common/pom.xml | 19 +- ...micDataSourceCreatorAutoConfiguration.java | 99 ++++----- dynamic-datasource-spring/pom.xml | 4 +- .../tx/AtomikosTransactionFactory.java | 1 - 20 files changed, 235 insertions(+), 289 deletions(-) create mode 100644 dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidConfigUtil.java diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 81e3bd6..7c3c75f 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,2 @@ # These are supported funding model platforms -custom: ['https://dynamic-datasource.com/guide/donate/'] +custom: [ 'https://dynamic-datasource.com/guide/donate/' ] \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 653f36d..5d2b047 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -23,13 +23,13 @@ include: Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or - advances + advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic - address, without explicit permission + address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a - professional setting + professional setting ## Our Responsibilities @@ -73,4 +73,4 @@ available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.ht [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq +https://www.contributor-covenant.org/faq \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0804ae6..f79bfc9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,5 @@ -# FORK +# FORK # RUN TEST -# PR +# PR \ No newline at end of file diff --git a/README.md b/README.md index 5565214..61d7bb2 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,6 @@ dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成 详细文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611 - # 特性 - 支持 **数据源分组** ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。 @@ -83,6 +82,7 @@ dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成 ${version} ``` + 2. 配置数据源。 ```yaml @@ -128,9 +128,9 @@ spring: spring: spri **@DS** 可以注解在方法上或类上,**同时存在就近原则 方法上注解 优先于 类上注解**。 -| 注解 | 结果 | -| :-----------: | :--------------------------------------: | -| 没有@DS | 默认数据源 | +| 注解 | 结果 | +|:-------------:|:-----------------------:| +| 没有@DS | 默认数据源 | | @DS("dsName") | dsName可以为组名也可以为具体某个库的名称 | ```java diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/atomikos/AtomikosDataSourceCreator.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/atomikos/AtomikosDataSourceCreator.java index de63990..391ccd9 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/atomikos/AtomikosDataSourceCreator.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/atomikos/AtomikosDataSourceCreator.java @@ -21,6 +21,8 @@ import com.baomidou.dynamic.datasource.creator.DataSourceProperty; import com.baomidou.dynamic.datasource.enums.DdConstants; import com.baomidou.dynamic.datasource.enums.XADataSourceEnum; import com.baomidou.dynamic.datasource.toolkit.ConfigMergeCreator; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; import javax.sql.DataSource; import java.util.Properties; @@ -32,6 +34,8 @@ import java.util.Properties; * @author jiazhifeng * @date 2023/03/02 10:20 */ +@NoArgsConstructor +@AllArgsConstructor public class AtomikosDataSourceCreator implements DataSourceCreator { private static final ConfigMergeCreator MERGE_CREATOR = new ConfigMergeCreator<>("AtomikosConfig", AtomikosConfig.class, AtomikosConfig.class); private AtomikosConfig atomikosConfig; diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/beecp/BeeCpDataSourceCreator.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/beecp/BeeCpDataSourceCreator.java index 0b19c07..d823bd3 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/beecp/BeeCpDataSourceCreator.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/beecp/BeeCpDataSourceCreator.java @@ -22,7 +22,8 @@ import com.baomidou.dynamic.datasource.creator.DataSourceProperty; import com.baomidou.dynamic.datasource.enums.DdConstants; import com.baomidou.dynamic.datasource.toolkit.ConfigMergeCreator; import com.baomidou.dynamic.datasource.toolkit.DsStrUtils; -import lombok.extern.slf4j.Slf4j; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; import javax.sql.DataSource; import java.lang.reflect.InvocationTargetException; @@ -35,7 +36,8 @@ import java.lang.reflect.Method; * @author TaoYu * @since 2020/5/14 */ -@Slf4j +@NoArgsConstructor +@AllArgsConstructor public class BeeCpDataSourceCreator implements DataSourceCreator { private static final ConfigMergeCreator MERGE_CREATOR = new ConfigMergeCreator<>("BeeCp", BeeCpConfig.class, BeeDataSourceConfig.class); diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/dbcp/Dbcp2DataSourceCreator.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/dbcp/Dbcp2DataSourceCreator.java index 5a5a6cd..206e558 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/dbcp/Dbcp2DataSourceCreator.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/dbcp/Dbcp2DataSourceCreator.java @@ -20,6 +20,8 @@ import com.baomidou.dynamic.datasource.creator.DataSourceProperty; import com.baomidou.dynamic.datasource.enums.DdConstants; import com.baomidou.dynamic.datasource.toolkit.ConfigMergeCreator; import com.baomidou.dynamic.datasource.toolkit.DsStrUtils; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; import lombok.SneakyThrows; import org.apache.commons.dbcp2.BasicDataSource; @@ -31,6 +33,8 @@ import javax.sql.DataSource; * @author TaoYu * @since 2021/5/18 */ +@NoArgsConstructor +@AllArgsConstructor public class Dbcp2DataSourceCreator implements DataSourceCreator { private static final ConfigMergeCreator MERGE_CREATOR = new ConfigMergeCreator<>("Dbcp2", Dbcp2Config.class, BasicDataSource.class); diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidConfig.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidConfig.java index 586f1d7..6220e9f 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidConfig.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidConfig.java @@ -15,7 +15,6 @@ */ package com.baomidou.dynamic.datasource.creator.druid; -import com.alibaba.druid.pool.DruidAbstractDataSource; import lombok.Data; import lombok.extern.slf4j.Slf4j; @@ -91,197 +90,4 @@ public class DruidConfig { private Map stat = new HashMap<>(); private List proxyFilters = new ArrayList<>(); - - /** - * 根据全局配置和本地配置结合转换为Properties - * - * @param g 全局配置 - * @return Druid配置 - */ - public Properties toProperties(DruidConfig g) { - Properties properties = new Properties(); - Integer initialSize = this.initialSize == null ? g.getInitialSize() : this.initialSize; - if (initialSize != null && !initialSize.equals(DruidAbstractDataSource.DEFAULT_INITIAL_SIZE)) { - properties.setProperty(DruidConsts.INITIAL_SIZE, String.valueOf(initialSize)); - } - - Integer maxActive = this.maxActive == null ? g.getMaxActive() : this.maxActive; - if (maxActive != null && !maxActive.equals(DruidAbstractDataSource.DEFAULT_MAX_WAIT)) { - properties.setProperty(DruidConsts.MAX_ACTIVE, String.valueOf(maxActive)); - } - - Integer minIdle = this.minIdle == null ? g.getMinIdle() : this.minIdle; - if (minIdle != null && !minIdle.equals(DruidAbstractDataSource.DEFAULT_MIN_IDLE)) { - properties.setProperty(DruidConsts.MIN_IDLE, String.valueOf(minIdle)); - } - - Integer maxWait = this.maxWait == null ? g.getMaxWait() : this.maxWait; - if (maxWait != null && !maxWait.equals(DruidAbstractDataSource.DEFAULT_MAX_WAIT)) { - properties.setProperty(DruidConsts.MAX_WAIT, String.valueOf(maxWait)); - } - - Long timeBetweenEvictionRunsMillis = - this.timeBetweenEvictionRunsMillis == null ? g.getTimeBetweenEvictionRunsMillis() : this.timeBetweenEvictionRunsMillis; - if (timeBetweenEvictionRunsMillis != null && !timeBetweenEvictionRunsMillis.equals(DruidAbstractDataSource.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS)) { - properties.setProperty(DruidConsts.TIME_BETWEEN_EVICTION_RUNS_MILLIS, String.valueOf(timeBetweenEvictionRunsMillis)); - } - - Long timeBetweenLogStatsMillis = - this.timeBetweenLogStatsMillis == null ? g.getTimeBetweenLogStatsMillis() : this.timeBetweenLogStatsMillis; - if (timeBetweenLogStatsMillis != null && timeBetweenLogStatsMillis > 0) { - properties.setProperty(DruidConsts.TIME_BETWEEN_LOG_STATS_MILLIS, String.valueOf(timeBetweenLogStatsMillis)); - } - - Long keepAliveBetweenTimeMillis = - this.keepAliveBetweenTimeMillis == null ? g.getKeepAliveBetweenTimeMillis() : this.keepAliveBetweenTimeMillis; - if (keepAliveBetweenTimeMillis != null && !keepAliveBetweenTimeMillis.equals(DruidAbstractDataSource.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS * 2)) { - properties.setProperty(DruidConsts.KEEPALIVE_BETWEEN_TIME_MILLIS, String.valueOf(keepAliveBetweenTimeMillis)); - } - - Long minEvictableIdleTimeMillis = - this.minEvictableIdleTimeMillis == null ? g.getMinEvictableIdleTimeMillis() : this.minEvictableIdleTimeMillis; - if (minEvictableIdleTimeMillis != null && !minEvictableIdleTimeMillis.equals(DruidAbstractDataSource.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS)) { - properties.setProperty(DruidConsts.MIN_EVICTABLE_IDLE_TIME_MILLIS, String.valueOf(minEvictableIdleTimeMillis)); - } - - Long maxEvictableIdleTimeMillis = - this.maxEvictableIdleTimeMillis == null ? g.getMaxEvictableIdleTimeMillis() : this.maxEvictableIdleTimeMillis; - if (maxEvictableIdleTimeMillis != null && !maxEvictableIdleTimeMillis.equals(DruidAbstractDataSource.DEFAULT_MAX_EVICTABLE_IDLE_TIME_MILLIS)) { - properties.setProperty(DruidConsts.MAX_EVICTABLE_IDLE_TIME_MILLIS, String.valueOf(maxEvictableIdleTimeMillis)); - } - - Boolean testWhileIdle = this.testWhileIdle == null ? g.getTestWhileIdle() : this.testWhileIdle; - if (testWhileIdle != null && !testWhileIdle.equals(DruidAbstractDataSource.DEFAULT_WHILE_IDLE)) { - properties.setProperty(DruidConsts.TEST_WHILE_IDLE, Boolean.FALSE.toString()); - } - - Boolean testOnBorrow = this.testOnBorrow == null ? g.getTestOnBorrow() : this.testOnBorrow; - if (testOnBorrow != null && !testOnBorrow.equals(DruidAbstractDataSource.DEFAULT_TEST_ON_BORROW)) { - properties.setProperty(DruidConsts.TEST_ON_BORROW, Boolean.TRUE.toString()); - } - - String validationQuery = this.validationQuery == null ? g.getValidationQuery() : this.validationQuery; - if (validationQuery != null && validationQuery.length() > 0) { - properties.setProperty(DruidConsts.VALIDATION_QUERY, validationQuery); - } - - Boolean useGlobalDataSourceStat = this.useGlobalDataSourceStat == null ? g.getUseGlobalDataSourceStat() : this.useGlobalDataSourceStat; - if (useGlobalDataSourceStat != null && useGlobalDataSourceStat.equals(Boolean.TRUE)) { - properties.setProperty(DruidConsts.USE_GLOBAL_DATA_SOURCE_STAT, Boolean.TRUE.toString()); - } - - Boolean asyncInit = this.asyncInit == null ? g.getAsyncInit() : this.asyncInit; - if (asyncInit != null && asyncInit.equals(Boolean.TRUE)) { - properties.setProperty(DruidConsts.ASYNC_INIT, Boolean.TRUE.toString()); - } - - //filters单独处理,默认了stat - String filters = this.filters == null ? g.getFilters() : this.filters; - if (filters == null) { - filters = DruidConsts.STAT_STR; - } - if (publicKey != null && publicKey.length() > 0 && !filters.contains(DruidConsts.CONFIG_STR)) { - filters += "," + DruidConsts.CONFIG_STR; - } - properties.setProperty(DruidConsts.FILTERS, filters); - - Boolean clearFiltersEnable = this.clearFiltersEnable == null ? g.getClearFiltersEnable() : this.clearFiltersEnable; - if (clearFiltersEnable != null && clearFiltersEnable.equals(Boolean.FALSE)) { - properties.setProperty(DruidConsts.CLEAR_FILTERS_ENABLE, Boolean.FALSE.toString()); - } - - Boolean resetStatEnable = this.resetStatEnable == null ? g.getResetStatEnable() : this.resetStatEnable; - if (resetStatEnable != null && resetStatEnable.equals(Boolean.FALSE)) { - properties.setProperty(DruidConsts.RESET_STAT_ENABLE, Boolean.FALSE.toString()); - } - - Integer notFullTimeoutRetryCount = - this.notFullTimeoutRetryCount == null ? g.getNotFullTimeoutRetryCount() : this.notFullTimeoutRetryCount; - if (notFullTimeoutRetryCount != null && !notFullTimeoutRetryCount.equals(0)) { - properties.setProperty(DruidConsts.NOT_FULL_TIMEOUT_RETRY_COUNT, String.valueOf(notFullTimeoutRetryCount)); - } - - Integer maxWaitThreadCount = this.maxWaitThreadCount == null ? g.getMaxWaitThreadCount() : this.maxWaitThreadCount; - if (maxWaitThreadCount != null && !maxWaitThreadCount.equals(-1)) { - properties.setProperty(DruidConsts.MAX_WAIT_THREAD_COUNT, String.valueOf(maxWaitThreadCount)); - } - - Boolean failFast = this.failFast == null ? g.getFailFast() : this.failFast; - if (failFast != null && failFast.equals(Boolean.TRUE)) { - properties.setProperty(DruidConsts.FAIL_FAST, Boolean.TRUE.toString()); - } - - Long phyTimeoutMillis = this.phyTimeoutMillis == null ? g.getPhyTimeoutMillis() : this.phyTimeoutMillis; - if (phyTimeoutMillis != null && !phyTimeoutMillis.equals(DruidAbstractDataSource.DEFAULT_PHY_TIMEOUT_MILLIS)) { - properties.setProperty(DruidConsts.PHY_TIMEOUT_MILLIS, String.valueOf(phyTimeoutMillis)); - } - - Long phyMaxUseCount = this.phyMaxUseCount == null ? g.getPhyMaxUseCount() : this.phyMaxUseCount; - if (phyMaxUseCount != null && !phyMaxUseCount.equals(-1)) { - properties.setProperty(DruidConsts.PHY_MAX_USE_COUNT, String.valueOf(phyMaxUseCount)); - } - - Boolean keepAlive = this.keepAlive == null ? g.getKeepAlive() : this.keepAlive; - if (keepAlive != null && keepAlive.equals(Boolean.TRUE)) { - properties.setProperty(DruidConsts.KEEP_ALIVE, Boolean.TRUE.toString()); - } - - Boolean poolPreparedStatements = this.poolPreparedStatements == null ? g.getPoolPreparedStatements() : this.poolPreparedStatements; - if (poolPreparedStatements != null && poolPreparedStatements.equals(Boolean.TRUE)) { - properties.setProperty(DruidConsts.POOL_PREPARED_STATEMENTS, Boolean.TRUE.toString()); - } - - Boolean initVariants = this.initVariants == null ? g.getInitVariants() : this.initVariants; - if (initVariants != null && initVariants.equals(Boolean.TRUE)) { - properties.setProperty(DruidConsts.INIT_VARIANTS, Boolean.TRUE.toString()); - } - - Boolean initGlobalVariants = this.initGlobalVariants == null ? g.getInitGlobalVariants() : this.initGlobalVariants; - if (initGlobalVariants != null && initGlobalVariants.equals(Boolean.TRUE)) { - properties.setProperty(DruidConsts.INIT_GLOBAL_VARIANTS, Boolean.TRUE.toString()); - } - - Boolean useUnfairLock = this.useUnfairLock == null ? g.getUseUnfairLock() : this.useUnfairLock; - if (useUnfairLock != null) { - properties.setProperty(DruidConsts.USE_UNFAIR_LOCK, String.valueOf(useUnfairLock)); - } - - Boolean killWhenSocketReadTimeout = - this.killWhenSocketReadTimeout == null ? g.getKillWhenSocketReadTimeout() : this.killWhenSocketReadTimeout; - if (killWhenSocketReadTimeout != null && killWhenSocketReadTimeout.equals(Boolean.TRUE)) { - properties.setProperty(DruidConsts.KILL_WHEN_SOCKET_READ_TIMEOUT, Boolean.TRUE.toString()); - } - - Properties connectProperties = connectionProperties == null ? g.getConnectionProperties() : connectionProperties; - - if (publicKey != null && publicKey.length() > 0) { - if (connectProperties == null) { - connectProperties = new Properties(); - } - connectProperties.setProperty("config.decrypt", Boolean.TRUE.toString()); - connectProperties.setProperty("config.decrypt.key", publicKey); - } - this.connectionProperties = connectProperties; - - Integer maxPoolPreparedStatementPerConnectionSize = - this.maxPoolPreparedStatementPerConnectionSize == null ? g.getMaxPoolPreparedStatementPerConnectionSize() - : this.maxPoolPreparedStatementPerConnectionSize; - if (maxPoolPreparedStatementPerConnectionSize != null && !maxPoolPreparedStatementPerConnectionSize.equals(10)) { - properties.setProperty(DruidConsts.MAX_POOL_PREPARED_STATEMENT_PER_CONNECTION_SIZE, String.valueOf(maxPoolPreparedStatementPerConnectionSize)); - } - - String initConnectionSqls = this.initConnectionSqls == null ? g.getInitConnectionSqls() : this.initConnectionSqls; - if (initConnectionSqls != null && initConnectionSqls.length() > 0) { - properties.setProperty(DruidConsts.INIT_CONNECTION_SQLS, initConnectionSqls); - } - return properties; - } - - public List getProxyFilters() { - return proxyFilters; - } - - public void setProxyFilters(List proxyFilters) { - this.proxyFilters = proxyFilters; - } } \ No newline at end of file diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidConfigUtil.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidConfigUtil.java new file mode 100644 index 0000000..06765c1 --- /dev/null +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidConfigUtil.java @@ -0,0 +1,86 @@ +/* + * Copyright © 2018 organization baomidou + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.baomidou.dynamic.datasource.creator.druid; + +import com.baomidou.dynamic.datasource.toolkit.DsConfigUtil; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.Properties; + +/** + * Druid配置工具类 + * + * @author TaoYu + * @since 4.0.0 + */ +@Slf4j +public final class DruidConfigUtil { + + private static final Map METHODS = DsConfigUtil.getGetterMethods(DruidConfig.class); + + /** + * 根据全局配置和本地配置结合转换为Properties + * + * @param g 全局配置 + * @param c 当前配置 + * @return Druid配置 + */ + @SneakyThrows + public static Properties mergeConfig(DruidConfig g, DruidConfig c) { + Properties properties = new Properties(); + for (Map.Entry entry : METHODS.entrySet()) { + String key = entry.getKey(); + Method readMethod = entry.getValue(); + Object cValue = readMethod.invoke(c); + if (cValue != null) { + properties.setProperty("druid." + key, String.valueOf(cValue)); + continue; + } + if (g != null) { + Object gValue = readMethod.invoke(g); + if (gValue != null) { + properties.setProperty("druid." + key, String.valueOf(gValue)); + } + } + } + + //filters单独处理,默认了stat +// String filters = this.filters == null ? g.getFilters() : this.filters; +// if (filters == null) { +// filters = DruidConsts.STAT_STR; +// } +// if (publicKey != null && publicKey.length() > 0 && !filters.contains(DruidConsts.CONFIG_STR)) { +// filters += "," + DruidConsts.CONFIG_STR; +// } +// properties.setProperty(DruidConsts.FILTERS, filters); +// +// Properties connectProperties = connectionProperties == null ? g.getConnectionProperties() : connectionProperties; +// +// if (publicKey != null && publicKey.length() > 0) { +// if (connectProperties == null) { +// connectProperties = new Properties(); +// } +// connectProperties.setProperty("config.decrypt", Boolean.TRUE.toString()); +// connectProperties.setProperty("config.decrypt.key", publicKey); +// } +// this.connectionProperties = connectProperties; + + return properties; + } +} \ No newline at end of file diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidDataSourceCreator.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidDataSourceCreator.java index 7fa11ee..f7fa458 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidDataSourceCreator.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidDataSourceCreator.java @@ -28,6 +28,8 @@ import com.baomidou.dynamic.datasource.creator.DataSourceProperty; import com.baomidou.dynamic.datasource.enums.DdConstants; import com.baomidou.dynamic.datasource.exception.ErrorCreateDataSourceException; import com.baomidou.dynamic.datasource.toolkit.DsStrUtils; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import javax.sql.DataSource; @@ -45,26 +47,41 @@ import java.util.Properties; * @since 2020/1/21 */ @Slf4j +@NoArgsConstructor +@AllArgsConstructor public class DruidDataSourceCreator implements DataSourceCreator { private static Method configMethod = null; static { - try { - Class aClass = DruidDataSource.class; - configMethod = aClass.getDeclaredMethod("configFromPropeties"); - if (configMethod == null) { - configMethod = aClass.getDeclaredMethod("configFromPropety"); - } - } catch (Exception ignore) { - - } + fetchMethod(); } // @Autowired(required = false) // private ApplicationContext applicationContext; private DruidConfig gConfig; + /** + * Druid since 1.2.17 use 'configFromPropeties' to copy config + * Druid < 1.2.17 use 'configFromPropety' to copy config + */ + @SuppressWarnings("JavaReflectionMemberAccess") + private static void fetchMethod() { + Class aClass = DruidDataSource.class; + try { + configMethod = aClass.getMethod("configFromPropeties", DruidDataSource.class); + return; + } catch (NoSuchMethodException ignored) { + } + + try { + configMethod = aClass.getMethod("configFromPropety", DruidDataSource.class); + return; + } catch (NoSuchMethodException ignored) { + } + throw new RuntimeException("Druid does not has 'configFromPropeties' or 'configFromPropety' method!"); + } + @Override public DataSource createDataSource(DataSourceProperty dataSourceProperty) { DruidDataSource dataSource = new DruidDataSource(); @@ -77,7 +94,7 @@ public class DruidDataSourceCreator implements DataSourceCreator { dataSource.setDriverClassName(driverClassName); } DruidConfig config = dataSourceProperty.getDruid(); - Properties properties = config.toProperties(gConfig); + Properties properties = DruidConfigUtil.mergeConfig(gConfig, config); List proxyFilters = this.initFilters(dataSourceProperty, properties.getProperty("druid.filters")); dataSource.setProxyFilters(proxyFilters); diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidLogConfigUtil.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidLogConfigUtil.java index d8595b0..c281297 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidLogConfigUtil.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidLogConfigUtil.java @@ -25,7 +25,7 @@ import java.util.Map; /** * Druid日志配置工具类 * - * @author Taoyu + * @author TaoYu * @since 3.5.0 */ @Slf4j diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidStatConfigUtil.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidStatConfigUtil.java index e316757..6871023 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidStatConfigUtil.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidStatConfigUtil.java @@ -25,7 +25,7 @@ import java.util.Map; /** * Druid监控配置工具类 * - * @author Taoyu + * @author TaoYu * @since 3.5.0 */ @Slf4j diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidWallConfigUtil.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidWallConfigUtil.java index 55dcbfc..e5932da 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidWallConfigUtil.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/druid/DruidWallConfigUtil.java @@ -25,7 +25,7 @@ import java.util.Map; /** * 防火墙配置工具类 * - * @author Taoyu + * @author TaoYu * @since 3.5.0 */ @Slf4j diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/hikaricp/HikariDataSourceCreator.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/hikaricp/HikariDataSourceCreator.java index f87be41..fa37c34 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/hikaricp/HikariDataSourceCreator.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/creator/hikaricp/HikariDataSourceCreator.java @@ -22,6 +22,8 @@ import com.baomidou.dynamic.datasource.toolkit.ConfigMergeCreator; import com.baomidou.dynamic.datasource.toolkit.DsStrUtils; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; import javax.sql.DataSource; import java.lang.reflect.InvocationTargetException; @@ -33,6 +35,8 @@ import java.lang.reflect.Method; * @author TaoYu * @since 2020/1/21 */ +@NoArgsConstructor +@AllArgsConstructor public class HikariDataSourceCreator implements DataSourceCreator { private static final ConfigMergeCreator MERGE_CREATOR = new ConfigMergeCreator<>("HikariCp", HikariCpConfig.class, HikariConfig.class); @@ -51,14 +55,15 @@ public class HikariDataSourceCreator implements DataSourceCreator { */ @SuppressWarnings("JavaReflectionMemberAccess") private static void fetchMethod() { + Class hikariConfigClass = HikariConfig.class; try { - configCopyMethod = HikariConfig.class.getMethod("copyState", HikariConfig.class); + configCopyMethod = hikariConfigClass.getMethod("copyState", hikariConfigClass); return; } catch (NoSuchMethodException ignored) { } try { - configCopyMethod = HikariConfig.class.getMethod("copyStateTo", HikariConfig.class); + configCopyMethod = hikariConfigClass.getMethod("copyStateTo", hikariConfigClass); return; } catch (NoSuchMethodException ignored) { } diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/toolkit/ConfigMergeCreator.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/toolkit/ConfigMergeCreator.java index e659eba..7e24eeb 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/toolkit/ConfigMergeCreator.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/toolkit/ConfigMergeCreator.java @@ -46,6 +46,9 @@ public class ConfigMergeCreator { @SneakyThrows public T create(C global, C item) { + if (configClazz.equals(targetClazz) && global == null) { + return (T) item; + } T result = targetClazz.newInstance(); BeanInfo beanInfo = Introspector.getBeanInfo(configClazz, Object.class); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); @@ -114,4 +117,4 @@ public class ConfigMergeCreator { } } -} +} \ No newline at end of file diff --git a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/toolkit/DsConfigUtil.java b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/toolkit/DsConfigUtil.java index aad721a..14139fc 100644 --- a/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/toolkit/DsConfigUtil.java +++ b/dynamic-datasource-creator/src/main/java/com/baomidou/dynamic/datasource/toolkit/DsConfigUtil.java @@ -26,7 +26,7 @@ import java.util.regex.Pattern; /** * 动态数据源配置相关工具类 * - * @author Taoyu + * @author TaoYu * @since 3.5.0 */ public final class DsConfigUtil { @@ -64,6 +64,26 @@ public final class DsConfigUtil { return map; } + /** + * 通过clazz获取对应的setter方法 + * + * @param clazz 类 + * @return setter方法 + */ + public static Map getGetterMethods(Class clazz) { + Map methodMap = new HashMap<>(); + try { + for (PropertyDescriptor pd : Introspector.getBeanInfo(clazz).getPropertyDescriptors()) { + Method method = pd.getReadMethod(); + if (method != null) { + methodMap.put(pd.getName(), method); + } + } + } catch (Exception ignore) { + } + return methodMap; + } + /** * 通过clazz获取对应的setter方法 * @@ -74,9 +94,9 @@ public final class DsConfigUtil { Map methodMap = new HashMap<>(); try { for (PropertyDescriptor pd : Introspector.getBeanInfo(clazz).getPropertyDescriptors()) { - Method writeMethod = pd.getWriteMethod(); - if (writeMethod != null) { - methodMap.put(pd.getName(), writeMethod); + Method method = pd.getWriteMethod(); + if (method != null) { + methodMap.put(pd.getName(), method); } } } catch (Exception ignore) { diff --git a/dynamic-datasource-spring-boot-common/pom.xml b/dynamic-datasource-spring-boot-common/pom.xml index e592669..2fb7f1d 100644 --- a/dynamic-datasource-spring-boot-common/pom.xml +++ b/dynamic-datasource-spring-boot-common/pom.xml @@ -18,13 +18,13 @@ - com.zaxxer - HikariCP-java7 + com.alibaba + druid true - com.alibaba - druid + com.zaxxer + HikariCP-java7 true @@ -37,6 +37,17 @@ commons-dbcp2 true + + com.atomikos + transactions-jdbc + true + + + + com.baomidou + mybatis-plus + true + org.springframework.boot diff --git a/dynamic-datasource-spring-boot-common/src/main/java/com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceCreatorAutoConfiguration.java b/dynamic-datasource-spring-boot-common/src/main/java/com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceCreatorAutoConfiguration.java index ac86b8a..3a2f267 100644 --- a/dynamic-datasource-spring-boot-common/src/main/java/com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceCreatorAutoConfiguration.java +++ b/dynamic-datasource-spring-boot-common/src/main/java/com/baomidou/dynamic/datasource/spring/boot/autoconfigure/DynamicDataSourceCreatorAutoConfiguration.java @@ -17,21 +17,26 @@ package com.baomidou.dynamic.datasource.spring.boot.autoconfigure; import cn.beecp.BeeDataSource; import com.alibaba.druid.pool.DruidDataSource; +import com.atomikos.jdbc.AtomikosDataSourceBean; import com.baomidou.dynamic.datasource.creator.DataSourceCreator; import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator; +import com.baomidou.dynamic.datasource.creator.atomikos.AtomikosDataSourceCreator; import com.baomidou.dynamic.datasource.creator.basic.BasicDataSourceCreator; import com.baomidou.dynamic.datasource.creator.beecp.BeeCpDataSourceCreator; import com.baomidou.dynamic.datasource.creator.dbcp.Dbcp2DataSourceCreator; import com.baomidou.dynamic.datasource.creator.druid.DruidDataSourceCreator; import com.baomidou.dynamic.datasource.creator.hikaricp.HikariDataSourceCreator; import com.baomidou.dynamic.datasource.creator.jndi.JndiDataSourceCreator; +import com.baomidou.dynamic.datasource.tx.AtomikosTransactionFactory; import com.zaxxer.hikari.HikariDataSource; +import lombok.RequiredArgsConstructor; import org.apache.commons.dbcp2.BasicDataSource; +import org.apache.ibatis.transaction.TransactionFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; import org.springframework.core.annotation.Order; import java.util.List; @@ -40,6 +45,8 @@ import java.util.List; * @author TaoYu */ @Configuration +@RequiredArgsConstructor +@EnableConfigurationProperties(DynamicDataSourceProperties.class) public class DynamicDataSourceCreatorAutoConfiguration { public static final int JNDI_ORDER = 1000; @@ -49,14 +56,14 @@ public class DynamicDataSourceCreatorAutoConfiguration { public static final int DBCP2_ORDER = 5000; public static final int ATOMIKOS_ORDER = 6000; public static final int DEFAULT_ORDER = 7000; + private final DynamicDataSourceProperties properties; - @Primary @Bean @ConditionalOnMissingBean public DefaultDataSourceCreator dataSourceCreator(List dataSourceCreators) { - DefaultDataSourceCreator defaultDataSourceCreator = new DefaultDataSourceCreator(); - defaultDataSourceCreator.setCreators(dataSourceCreators); - return defaultDataSourceCreator; + DefaultDataSourceCreator creator = new DefaultDataSourceCreator(); + creator.setCreators(dataSourceCreators); + return creator; } @Bean @@ -74,76 +81,58 @@ public class DynamicDataSourceCreatorAutoConfiguration { /** * 存在Druid数据源时, 加入创建器 */ - @ConditionalOnClass(DruidDataSource.class) - @Configuration - static class DruidDataSourceCreatorConfiguration { - @Bean - @Order(DRUID_ORDER) - public DruidDataSourceCreator druidDataSourceCreator() { - return new DruidDataSourceCreator(); - } + @Bean + @Order(DRUID_ORDER) + @ConditionalOnClass(DruidDataSource.class) + public DruidDataSourceCreator druidDataSourceCreator() { + return new DruidDataSourceCreator(properties.getDruid()); } /** * 存在Hikari数据源时, 加入创建器 */ + @Bean + @Order(HIKARI_ORDER) @ConditionalOnClass(HikariDataSource.class) - @Configuration - static class HikariDataSourceCreatorConfiguration { - @Bean - @Order(HIKARI_ORDER) - public HikariDataSourceCreator hikariDataSourceCreator() { - return new HikariDataSourceCreator(); - } + public HikariDataSourceCreator hikariDataSourceCreator() { + return new HikariDataSourceCreator(properties.getHikari()); } /** * 存在BeeCp数据源时, 加入创建器 */ + @Bean + @Order(BEECP_ORDER) @ConditionalOnClass(BeeDataSource.class) - @Configuration - static class BeeCpDataSourceCreatorConfiguration { - - @Bean - @Order(BEECP_ORDER) - public BeeCpDataSourceCreator beeCpDataSourceCreator() { - return new BeeCpDataSourceCreator(); - } + public BeeCpDataSourceCreator beeCpDataSourceCreator() { + return new BeeCpDataSourceCreator(properties.getBeecp()); } /** * 存在Dbcp2数据源时, 加入创建器 */ + @Bean + @Order(DBCP2_ORDER) @ConditionalOnClass(BasicDataSource.class) - @Configuration - static class Dbcp2DataSourceCreatorConfiguration { - - @Bean - @Order(DBCP2_ORDER) - public Dbcp2DataSourceCreator dbcp2DataSourceCreator() { - return new Dbcp2DataSourceCreator(); - } + public Dbcp2DataSourceCreator dbcp2DataSourceCreator() { + return new Dbcp2DataSourceCreator(properties.getDbcp2()); } -// /** -// * 存在Atomikos数据源时, 加入创建器 -// */ -// @ConditionalOnClass({AtomikosDataSourceBean.class}) -// @Configuration -// static class AtomikosDataSourceCreatorConfiguration { -// -// @Bean -// @Order(ATOMIKOS_ORDER) -// public AtomikosDataSourceCreator atomikosDataSourceCreator() { -// return new AtomikosDataSourceCreator(); -// } -// -// @Bean -// @ConditionalOnClass(TransactionFactory) -// public TransactionFactory atomikosTransactionFactory() { -// return new AtomikosTransactionFactory(); -// } -// } + /** + * 存在Atomikos数据源时, 加入创建器 + */ + @Bean + @Order(ATOMIKOS_ORDER) + @ConditionalOnClass({AtomikosDataSourceBean.class}) + public AtomikosDataSourceCreator atomikosDataSourceCreator() { + return new AtomikosDataSourceCreator(properties.getAtomikos()); + } + + @Bean + @ConditionalOnClass({AtomikosDataSourceBean.class, TransactionFactory.class}) + public TransactionFactory atomikosTransactionFactory() { + return new AtomikosTransactionFactory(); + } } \ No newline at end of file diff --git a/dynamic-datasource-spring/pom.xml b/dynamic-datasource-spring/pom.xml index b45de02..9984e5b 100644 --- a/dynamic-datasource-spring/pom.xml +++ b/dynamic-datasource-spring/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/dynamic-datasource-spring/src/main/java/com/baomidou/dynamic/datasource/tx/AtomikosTransactionFactory.java b/dynamic-datasource-spring/src/main/java/com/baomidou/dynamic/datasource/tx/AtomikosTransactionFactory.java index cbe10a2..04af6bb 100644 --- a/dynamic-datasource-spring/src/main/java/com/baomidou/dynamic/datasource/tx/AtomikosTransactionFactory.java +++ b/dynamic-datasource-spring/src/main/java/com/baomidou/dynamic/datasource/tx/AtomikosTransactionFactory.java @@ -35,7 +35,6 @@ public class AtomikosTransactionFactory extends SpringManagedTransactionFactory public Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit) { DataSource determineDataSource = dataSource; - // e.g:ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (dataSource instanceof DynamicRoutingDataSource) { determineDataSource = ((DynamicRoutingDataSource) dataSource).determineDataSource(); }