diff --git a/TODO.md b/TODO.md index c397459..3deffcd 100644 --- a/TODO.md +++ b/TODO.md @@ -1,4 +1,11 @@ # TODO -1. 新增 `ConfigFilter` 的配置,替换默认的 ConnectProperties 方式 -2. 新增 `@EnableDynamicDruidDataSource`,自动配置动态数据源 \ No newline at end of file +## Add +* ~~新增 ConfigFilter 配置,替换默认的 `connectProperties` 方式~~ +* 新增 `@EnableDynamicDruidDataSource`,自动配置动态数据源 + +## Bug +* ~~`spring.datasource.schema` 会执行两次~~ + +## Optimize: +* `DataSourceCustomizer` 方式自定义数据源 \ No newline at end of file diff --git a/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/DataSourceInitializerConfiguration.java b/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/DataSourceInitializerConfiguration.java deleted file mode 100644 index 4745610..0000000 --- a/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/DataSourceInitializerConfiguration.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.github.trang.druid; - -import com.github.trang.druid.datasource.init.DataSourceInitializer; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; - -/** - * 支持数据源初始化时执行 SQL - * - * 照搬自 #{@link org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer} - * - * 在多数据源场景下,#{@link DataSourceAutoConfiguration} 会报 #{@code DataSource} 和 - * #{@code DataSourceInitializer} 的循环依赖,目前的解决办法是排除 #{@link DataSourceAutoConfiguration}, - * 但是这样一来,Spring Boot 在数据源初始化时执行 SQL 的特性会被移除,此类是为了保留该特性 - * - * @author trang - */ -public class DataSourceInitializerConfiguration { - - @Bean - @ConditionalOnMissingBean(DataSourceInitializer.class) - public com.github.trang.druid.datasource.init.DataSourceInitializer customDataSourceInitializer - (DataSourceProperties properties, ApplicationContext applicationContext) { - return new DataSourceInitializer(properties, applicationContext); - } - -} diff --git a/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/DruidAutoConfiguration.java b/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/DruidAutoConfiguration.java index d7b47b5..30abcfb 100644 --- a/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/DruidAutoConfiguration.java +++ b/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/DruidAutoConfiguration.java @@ -10,6 +10,7 @@ import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.wall.WallConfig; import com.alibaba.druid.wall.WallFilter; import com.github.trang.druid.datasource.DruidParentDataSource; +import com.github.trang.druid.properties.DruidFilterProperties.DruidConfigFilterProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -26,6 +27,7 @@ import org.springframework.context.annotation.Import; import javax.sql.DataSource; +import static com.github.trang.druid.properties.DruidFilterProperties.DruidConfigFilterProperties.*; import static com.github.trang.druid.properties.DruidProperties.*; /** @@ -36,8 +38,8 @@ import static com.github.trang.druid.properties.DruidProperties.*; @Configuration @ConditionalOnClass(DruidDataSource.class) @AutoConfigureBefore(DataSourceAutoConfiguration.class) -@EnableConfigurationProperties(DataSourceProperties.class) -@Import({DruidStatConfiguration.class, DruidServletConfiguration.class, DataSourceInitializerConfiguration.class}) +@EnableConfigurationProperties({DataSourceProperties.class, DruidConfigFilterProperties.class}) +@Import({DruidStatConfiguration.class, DruidServletConfiguration.class}) public class DruidAutoConfiguration { private static final Logger log = LoggerFactory.getLogger(DruidAutoConfiguration.class); @@ -70,7 +72,6 @@ public class DruidAutoConfiguration { @ConditionalOnProperty(prefix = DRUID_CONFIG_FILTER_PREFIX, name = "enabled", havingValue = "true") @Bean - @ConfigurationProperties(DRUID_CONFIG_FILTER_PREFIX) public ConfigFilter configFilter() { log.debug("druid config-filter init..."); return new ConfigFilter(); diff --git a/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/DruidDataSourceInitializerAutoConfiguration.java b/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/DruidDataSourceInitializerAutoConfiguration.java new file mode 100644 index 0000000..3b1a3ba --- /dev/null +++ b/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/DruidDataSourceInitializerAutoConfiguration.java @@ -0,0 +1,40 @@ +package com.github.trang.druid; + +import com.github.trang.druid.datasource.init.DruidDataSourceInitializer; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; + +/** + * 支持数据源初始化时执行 SQL + * + * 照搬自 #{@link org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer} + * + * 在多数据源场景下,#{@link DataSourceAutoConfiguration} 会报 #{@code DataSource} 和 + * #{@code DruidDataSourceInitializer} 的循环依赖,目前的解决办法是排除 #{@link DataSourceAutoConfiguration}, + * 但是这样一来,Spring Boot 在数据源初始化时执行 SQL 的特性会被移除,此类是为了保留该特性 + * + * @author trang + */ +@Configuration +@AutoConfigureAfter(DataSourceAutoConfiguration.class) +@ConditionalOnBean(DataSource.class) +public class DruidDataSourceInitializerAutoConfiguration { + + @Bean + @ConditionalOnMissingBean( + type = "org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer", + value = DruidDataSourceInitializer.class) + public DruidDataSourceInitializer druidDataSourceInitializer(DataSourceProperties properties, + ApplicationContext applicationContext) { + return new DruidDataSourceInitializer(properties, applicationContext); + } + +} diff --git a/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/datasource/DruidParentDataSource.java b/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/datasource/DruidParentDataSource.java index a5568eb..93ed014 100644 --- a/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/datasource/DruidParentDataSource.java +++ b/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/datasource/DruidParentDataSource.java @@ -9,6 +9,7 @@ import com.alibaba.druid.filter.logging.Slf4jLogFilter; import com.alibaba.druid.filter.stat.StatFilter; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.wall.WallFilter; +import com.github.trang.druid.properties.DruidFilterProperties.DruidConfigFilterProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -46,9 +47,40 @@ public abstract class DruidParentDataSource extends DruidDataSource { // 不使用 @Value 注入,避免因为找不到值抛出 NPE @Autowired private DataSourceProperties dataSourceProperties; + @Autowired + private DruidConfigFilterProperties druidConfigFilterProperties; @PostConstruct - public void initCommonParams() { + public void initDruidParentProperties() { + initDataSourceProperties(); + initConfigFilterProperties(); + initFilters(); + } + + private void initFilters() { + List filters = super.getProxyFilters(); + Stream.of(statFilter, wallFilter, configFilter, slf4jLogFilter, log4jFilter, log4j2Filter, commonsLogFilter) + .filter(Objects::nonNull) + .filter(filter -> !filters.contains(filter)) + .forEach(filters::add); + } + + private void initConfigFilterProperties() { + if (druidConfigFilterProperties.isEnabled()) { + StringBuilder builder = new StringBuilder(); + builder.append(ConfigFilter.CONFIG_DECRYPT).append("=").append("true").append(";"); + if (!StringUtils.isEmpty(druidConfigFilterProperties.getKey())) { + builder.append(ConfigFilter.CONFIG_KEY).append("=").append(druidConfigFilterProperties.getKey()); + builder.append(";"); + } + if (!StringUtils.isEmpty(druidConfigFilterProperties.getFile())) { + builder.append(ConfigFilter.CONFIG_FILE).append("=").append(druidConfigFilterProperties.getFile()); + } + super.setConnectionProperties(builder.toString()); + } + } + + private void initDataSourceProperties() { if (!StringUtils.isEmpty(dataSourceProperties.getDriverClassName())) { super.setDriverClassName(dataSourceProperties.getDriverClassName()); } @@ -61,12 +93,6 @@ public abstract class DruidParentDataSource extends DruidDataSource { if (!StringUtils.isEmpty(dataSourceProperties.getPassword())) { super.setPassword(dataSourceProperties.getPassword()); } - List filters = super.getProxyFilters(); - Stream.of(statFilter, wallFilter, configFilter, slf4jLogFilter, log4jFilter, log4j2Filter, - commonsLogFilter) - .filter(Objects::nonNull) - .filter(filter -> !filters.contains(filter)) - .forEach(filters::add); } } \ No newline at end of file diff --git a/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/datasource/init/DataSourceInitializer.java b/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/datasource/init/DruidDataSourceInitializer.java similarity index 94% rename from druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/datasource/init/DataSourceInitializer.java rename to druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/datasource/init/DruidDataSourceInitializer.java index 9e35c79..f9913b1 100644 --- a/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/datasource/init/DataSourceInitializer.java +++ b/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/datasource/init/DruidDataSourceInitializer.java @@ -31,11 +31,11 @@ import java.util.List; * @author Stephane Nicoll * @author Kazuki Shimizu * @since 1.1.0 - * @see com.github.trang.druid.DataSourceInitializerConfiguration + * @see com.github.trang.druid.DruidDataSourceInitializerAutoConfiguration */ -public class DataSourceInitializer implements ApplicationListener { +public class DruidDataSourceInitializer implements ApplicationListener { - private static final Logger logger = LoggerFactory.getLogger(DataSourceInitializer.class); + private static final Logger logger = LoggerFactory.getLogger(DruidDataSourceInitializer.class); private final DataSourceProperties properties; @@ -45,8 +45,8 @@ public class DataSourceInitializer implements ApplicationListener