feat: creator support no global Config

This commit is contained in:
TaoYu 2023-05-10 14:44:15 +08:00
parent 877249df89
commit 026262c598
20 changed files with 235 additions and 289 deletions

2
.github/FUNDING.yml vendored
View File

@ -1,2 +1,2 @@
# These are supported funding model platforms
custom: ['https://dynamic-datasource.com/guide/donate/']
custom: [ 'https://dynamic-datasource.com/guide/donate/' ]

View File

@ -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

View File

@ -1,5 +1,5 @@
# FORK
# FORK
# RUN TEST
# PR
# PR

View File

@ -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>${version}</version>
</dependency>
```
2. 配置数据源。
```yaml
@ -128,9 +128,9 @@ spring: spring: spri
**@DS** 可以注解在方法上或类上,**同时存在就近原则 方法上注解 优先于 类上注解**。
| 注解 | 结果 |
| :-----------: | :--------------------------------------: |
| 没有@DS | 默认数据源 |
| 注解 | 结果 |
|:-------------:|:-----------------------:|
| 没有@DS | 默认数据源 |
| @DS("dsName") | dsName可以为组名也可以为具体某个库的名称 |
```java

View File

@ -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 <a href="mailto:312290710@qq.com">jiazhifeng</a>
* @date 2023/03/02 10:20
*/
@NoArgsConstructor
@AllArgsConstructor
public class AtomikosDataSourceCreator implements DataSourceCreator {
private static final ConfigMergeCreator<AtomikosConfig, AtomikosConfig> MERGE_CREATOR = new ConfigMergeCreator<>("AtomikosConfig", AtomikosConfig.class, AtomikosConfig.class);
private AtomikosConfig atomikosConfig;

View File

@ -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<BeeCpConfig, BeeDataSourceConfig> MERGE_CREATOR = new ConfigMergeCreator<>("BeeCp", BeeCpConfig.class, BeeDataSourceConfig.class);

View File

@ -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<Dbcp2Config, BasicDataSource> MERGE_CREATOR = new ConfigMergeCreator<>("Dbcp2", Dbcp2Config.class, BasicDataSource.class);

View File

@ -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<String, Object> stat = new HashMap<>();
private List<String> 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<String> getProxyFilters() {
return proxyFilters;
}
public void setProxyFilters(List<String> proxyFilters) {
this.proxyFilters = proxyFilters;
}
}

View File

@ -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<String, Method> 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<String, Method> 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;
}
}

View File

@ -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<DruidDataSource> 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<DruidDataSource> 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<Filter> proxyFilters = this.initFilters(dataSourceProperty, properties.getProperty("druid.filters"));
dataSource.setProxyFilters(proxyFilters);

View File

@ -25,7 +25,7 @@ import java.util.Map;
/**
* Druid日志配置工具类
*
* @author Taoyu
* @author TaoYu
* @since 3.5.0
*/
@Slf4j

View File

@ -25,7 +25,7 @@ import java.util.Map;
/**
* Druid监控配置工具类
*
* @author Taoyu
* @author TaoYu
* @since 3.5.0
*/
@Slf4j

View File

@ -25,7 +25,7 @@ import java.util.Map;
/**
* 防火墙配置工具类
*
* @author Taoyu
* @author TaoYu
* @since 3.5.0
*/
@Slf4j

View File

@ -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<HikariCpConfig, HikariConfig> 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<HikariConfig> 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) {
}

View File

@ -46,6 +46,9 @@ public class ConfigMergeCreator<C, T> {
@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<C, T> {
}
}
}
}

View File

@ -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<String, Method> getGetterMethods(Class<?> clazz) {
Map<String, Method> 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<String, Method> 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) {

View File

@ -18,13 +18,13 @@
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java7</artifactId>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java7</artifactId>
<optional>true</optional>
</dependency>
<dependency>
@ -37,6 +37,17 @@
<artifactId>commons-dbcp2</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.atomikos</groupId>
<artifactId>transactions-jdbc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -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<DataSourceCreator> 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();
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>

View File

@ -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();
}