From 8ec0f4d212e1b121ec67bbb98e78f7ed9cd26a7a Mon Sep 17 00:00:00 2001 From: trang Date: Fri, 17 Nov 2017 12:37:55 +0800 Subject: [PATCH] 1.1.2 --- .../trang/druid/config/DynamicDataSource.java | 3 +- .../druid/config/SpringDataSourceConfig.java | 41 ++--- .../main/resources/application-dynamic.yml | 18 --- .../src/main/resources/application.yml | 89 ++++------ .../trang/druid/test/DevProfilesTests.java | 28 ---- .../druid/test/DynamicDataSourceTests.java | 87 ++++++++++ .../druid/test/DynamicDevProfilesTests.java | 39 ----- .../druid/test/SingleDataSourceTests.java | 2 + .../application-dev-props.properties | 2 - .../application-dynamic-dev-props.properties | 5 - .../autoconfigure/DruidAutoConfiguration.java | 153 +++++++++++++----- ...ataSourceInitializerAutoConfiguration.java | 4 +- .../datasource/DruidDataSource2.java | 2 +- .../datasource/DruidDataSource2Support.java | 4 +- .../properties/DruidDataSourceProperties.java | 3 - 15 files changed, 252 insertions(+), 228 deletions(-) delete mode 100644 druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/resources/application-dynamic.yml delete mode 100644 druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DevProfilesTests.java delete mode 100644 druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DynamicDevProfilesTests.java delete mode 100644 druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/resources/application-dev-props.properties delete mode 100644 druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/resources/application-dynamic-dev-props.properties diff --git a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/java/com/github/trang/druid/config/DynamicDataSource.java b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/java/com/github/trang/druid/config/DynamicDataSource.java index 5e51775..c7672df 100644 --- a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/java/com/github/trang/druid/config/DynamicDataSource.java +++ b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/java/com/github/trang/druid/config/DynamicDataSource.java @@ -1,5 +1,6 @@ package com.github.trang.druid.config; +import lombok.Getter; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import javax.sql.DataSource; @@ -18,7 +19,7 @@ public class DynamicDataSource extends AbstractRoutingDataSource { private AtomicInteger count = new AtomicInteger(); private DataSource defaultTargetDataSource; - private Map targetDataSources; + @Getter private Map targetDataSources; public DynamicDataSource(DataSource defaultTargetDataSource, Map targetDataSources) { this.defaultTargetDataSource = defaultTargetDataSource; diff --git a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/java/com/github/trang/druid/config/SpringDataSourceConfig.java b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/java/com/github/trang/druid/config/SpringDataSourceConfig.java index afcb797..5b190d2 100644 --- a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/java/com/github/trang/druid/config/SpringDataSourceConfig.java +++ b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/java/com/github/trang/druid/config/SpringDataSourceConfig.java @@ -1,17 +1,19 @@ package com.github.trang.druid.config; import com.alibaba.druid.pool.DruidDataSource; -import com.github.trang.druid.autoconfigure.datasource.DruidDataSource2; import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Profile; import javax.sql.DataSource; -import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.function.Function; + +import static java.util.stream.Collectors.toMap; /** * 多数据源配置,只在 #{@code spring.profiles.active=dynamic} 时生效 @@ -23,36 +25,15 @@ import java.util.Map; @Slf4j public class SpringDataSourceConfig { - /** - * 第一个数据源,注意数据源类型为 #{@link DruidDataSource2} - * - * `spring.datasource.druid.one` 前缀的配置会注入到该 Bean,同时会继承 `spring.datasource.druid` - * 前缀的配置,若名称相同则会被 `spring.datasource.druid.one` 覆盖 - */ - @Bean(initMethod = "init", destroyMethod = "close") - @ConfigurationProperties("spring.datasource.druid.data-sources.one") - public DruidDataSource oneDataSource() { - log.debug("druid first-data-source init..."); - return new DruidDataSource2(); - } - - /** - * 第二个数据源,若还有其它数据源可以继续增加 - */ - @Bean(initMethod = "init", destroyMethod = "close") - @ConfigurationProperties("spring.datasource.druid.data-sources.two") - public DruidDataSource twoDataSource() { - log.debug("druid second-data-source init..."); - return new DruidDataSource2(); - } + @Autowired + private List dataSourceList; @Bean @Primary - public DynamicDataSource dataSource(DruidDataSource oneDataSource, DruidDataSource twoDataSource) { - Map targetDataSources = new HashMap<>(8); - targetDataSources.put(oneDataSource.getName(), oneDataSource); - targetDataSources.put(twoDataSource.getName(), twoDataSource); - return new DynamicDataSource(oneDataSource, targetDataSources); + public DynamicDataSource dataSource() { + Map dataSourceMap = dataSourceList.stream() + .collect(toMap(DruidDataSource::getName, Function.identity())); + return new DynamicDataSource(dataSourceMap.get("first"), dataSourceMap); } } \ No newline at end of file diff --git a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/resources/application-dynamic.yml b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/resources/application-dynamic.yml deleted file mode 100644 index af25743..0000000 --- a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/resources/application-dynamic.yml +++ /dev/null @@ -1,18 +0,0 @@ -debug: false - -spring: - autoconfigure: - exclude: - # 多数据源场景会导致 `javax.sql.DataSource` 和 `org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer` - # 循环依赖,所以需要手动排除 `org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration` - - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration - datasource: - druid: - # 继承 spring.datasource.druid 前缀的配置,同时可以自定义配置,若名称相同则覆盖父配置 - data-sources: - one: - max-active: 50 - max-open-prepared-statements: 50 - two: - max-active: 25 - max-open-prepared-statements: 25 \ No newline at end of file diff --git a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/resources/application.yml b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/resources/application.yml index 9e0befe..39e90c3 100644 --- a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/resources/application.yml +++ b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/main/resources/application.yml @@ -11,7 +11,7 @@ logging: spring: profiles: # 默认环境为 default,多数据源演示请改为 dynamic - active: dynamic + active: default output: ansi: enabled: detect @@ -77,6 +77,35 @@ mybatis: --- +debug: true + +spring: + profiles: default + +--- + +debug: true + +spring: + profiles: dynamic + autoconfigure: + exclude: + # 多数据源场景会导致 `javax.sql.DataSource` 和 `org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer` + # 循环依赖,所以需要手动排除 `org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration` + - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration + datasource: + druid: + # 继承 spring.datasource.druid 前缀的配置,同时可以自定义配置,若名称相同则覆盖父配置 + data-sources: + first: + max-active: 50 + max-open-prepared-statements: 50 + second: + max-active: 25 + max-open-prepared-statements: 25 + +--- + debug: false spring: @@ -90,60 +119,4 @@ endpoints: actuator: enabled: true druid: - enabled: true - ---- - -debug: false - -spring: - profiles: default - ---- - -debug: false - -spring: - profiles: dynamic - autoconfigure: - exclude: - # 多数据源场景会导致 `javax.sql.DataSource` 和 `org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer` - # 循环依赖,所以需要手动排除 `org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration` - - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration - datasource: - druid: - # 继承 spring.datasource.druid 前缀的配置,同时可以自定义配置,若名称相同则覆盖父配置 - data-sources: - one: - max-active: 50 - max-open-prepared-statements: 50 - two: - max-active: 25 - max-open-prepared-statements: 25 - ---- - -spring: - profiles: dev-yaml - datasource: - druid: - min-evictable-idle-time-millis: 100000 - max-evictable-idle-time-millis: 200000 - ---- - -spring: - profiles: dynamic-dev-yaml - autoconfigure: - exclude: - - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration - datasource: - druid: - one: - name: one - min-evictable-idle-time-millis: 100001 - max-evictable-idle-time-millis: 200001 - two: - name: two - min-evictable-idle-time-millis: 100002 - max-evictable-idle-time-millis: 200002 \ No newline at end of file + enabled: true \ No newline at end of file diff --git a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DevProfilesTests.java b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DevProfilesTests.java deleted file mode 100644 index 2ba95dd..0000000 --- a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DevProfilesTests.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.github.trang.druid.test; - -import com.alibaba.druid.pool.DruidDataSource; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ActiveProfiles; - -import static org.junit.Assert.assertEquals; - -/** - * 单数据源测试 - * - * @author trang - */ -@ActiveProfiles("dev-yaml") -//@ActiveProfiles("dev-props") -public class DevProfilesTests extends BaseTest { - - @Autowired - private DruidDataSource dataSource; - - @Test - public void testSingleDataSource() { - assertEquals(100000, dataSource.getMinEvictableIdleTimeMillis()); - assertEquals(200000, dataSource.getMaxEvictableIdleTimeMillis()); - } - -} \ No newline at end of file diff --git a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DynamicDataSourceTests.java b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DynamicDataSourceTests.java index 0e5dfd2..e94da71 100644 --- a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DynamicDataSourceTests.java +++ b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DynamicDataSourceTests.java @@ -1,11 +1,18 @@ package com.github.trang.druid.test; import com.alibaba.druid.pool.DruidDataSource; +import com.github.trang.druid.autoconfigure.datasource.DruidDataSource2; import com.github.trang.druid.config.DynamicDataSource; +import org.junit.Assert; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ActiveProfiles; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + import static org.junit.Assert.assertEquals; /** @@ -57,4 +64,84 @@ public class DynamicDataSourceTests extends BaseTest { assertEquals(true, secondDataSource.isUseGlobalDataSourceStat()); } + @Test + public void testDynamicDataSource() { + assertEquals(dataSource.getTargetDataSources().size(), 2); + } + + + @Autowired(required = false) + private Map dataSourceMap; + @Autowired(required = false) + private Map druidDataSourceMap; + @Autowired(required = false) + private Map foolDataSourceMap; + @Autowired(required = false) + private List dataSourceList; + @Autowired(required = false) + private List dataSources; + @Autowired(required = false) + private List druidDataSourceList; + @Autowired(required = false) + private List druidDataSources; + @Autowired(required = false) + private List foolDataSources; + @Autowired(required = false) + private Collection druidDataSourceCollection; + @Autowired(required = false) + private Set druidDataSourceSet; + @Autowired(required = false) + private DruidDataSource[] druidDataSourceArray; + + + @Autowired(required = false) + private Map dataSource2Map; + @Autowired(required = false) + private Map druidDataSource2Map; + @Autowired(required = false) + private Map foolDataSource2Map; + @Autowired(required = false) + private List dataSource2List; + @Autowired(required = false) + private List dataSources2; + @Autowired(required = false) + private List druidDataSource2List; + @Autowired(required = false) + private List druidDataSources2; + @Autowired(required = false) + private List foolDataSources2; + @Autowired(required = false) + private Collection druidDataSource2Collection; + @Autowired(required = false) + private Set druidDataSource2Set; + @Autowired(required = false) + private DruidDataSource2[] druidDataSource2Array; + + @Test + public void autowire() { + Assert.assertNotNull(dataSourceMap); + Assert.assertNotNull(druidDataSourceMap); + Assert.assertNotNull(foolDataSourceMap); + Assert.assertNotNull(dataSourceList); + Assert.assertNotNull(dataSources); + Assert.assertNotNull(druidDataSourceList); + Assert.assertNotNull(druidDataSources); + Assert.assertNotNull(foolDataSources); + Assert.assertNotNull(druidDataSourceCollection); + Assert.assertNotNull(druidDataSourceSet); + Assert.assertNotNull(druidDataSourceArray); + + Assert.assertNotNull(dataSource2Map); + Assert.assertNotNull(druidDataSource2Map); + Assert.assertNotNull(foolDataSource2Map); + Assert.assertNotNull(dataSource2List); + Assert.assertNotNull(dataSources2); + Assert.assertNotNull(druidDataSource2List); + Assert.assertNotNull(druidDataSources2); + Assert.assertNotNull(foolDataSources2); + Assert.assertNotNull(druidDataSource2Collection); + Assert.assertNotNull(druidDataSource2Set); + Assert.assertNotNull(druidDataSource2Array); + } + } \ No newline at end of file diff --git a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DynamicDevProfilesTests.java b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DynamicDevProfilesTests.java deleted file mode 100644 index cb93687..0000000 --- a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/DynamicDevProfilesTests.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.github.trang.druid.test; - -import com.alibaba.druid.pool.DruidDataSource; -import com.github.trang.druid.config.DynamicDataSource; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ActiveProfiles; - -import static org.junit.Assert.assertEquals; - -/** - * 动态数据源测试 - * - * @author trang - */ -@ActiveProfiles("dynamic-dev-yaml") -//@ActiveProfiles("dynamic-dev-props") -public class DynamicDevProfilesTests extends BaseTest { - - @Autowired - private DruidDataSource firstDataSource; - @Autowired - private DruidDataSource secondDataSource; - @Autowired - private DynamicDataSource dataSource; - - @Test - public void testFirstDataSource() { - assertEquals(100001, firstDataSource.getMinEvictableIdleTimeMillis()); - assertEquals(200001, firstDataSource.getMaxEvictableIdleTimeMillis()); - } - - @Test - public void testSecondDataSource() { - assertEquals(100002, secondDataSource.getMinEvictableIdleTimeMillis()); - assertEquals(200002, secondDataSource.getMaxEvictableIdleTimeMillis()); - } - -} \ No newline at end of file diff --git a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/SingleDataSourceTests.java b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/SingleDataSourceTests.java index f6c98dc..e4f701b 100644 --- a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/SingleDataSourceTests.java +++ b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/java/com/github/trang/druid/test/SingleDataSourceTests.java @@ -3,6 +3,7 @@ package com.github.trang.druid.test; import com.alibaba.druid.pool.DruidDataSource; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ActiveProfiles; import static org.junit.Assert.assertEquals; @@ -11,6 +12,7 @@ import static org.junit.Assert.assertEquals; * * @author trang */ +@ActiveProfiles("default") public class SingleDataSourceTests extends BaseTest { @Autowired diff --git a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/resources/application-dev-props.properties b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/resources/application-dev-props.properties deleted file mode 100644 index 3842461..0000000 --- a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/resources/application-dev-props.properties +++ /dev/null @@ -1,2 +0,0 @@ -spring.datasource.druid.min-evictable-idle-time-millis=100000 -spring.datasource.druid.max-evictable-idle-time-millis=200000 \ No newline at end of file diff --git a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/resources/application-dynamic-dev-props.properties b/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/resources/application-dynamic-dev-props.properties deleted file mode 100644 index 616dffd..0000000 --- a/druid-spring-boot-example/druid-spring-boot-mybatis-example/src/test/resources/application-dynamic-dev-props.properties +++ /dev/null @@ -1,5 +0,0 @@ -spring.autoconfigure.exclude=- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration -spring.datasource.druid.one.min-evictable-idle-time-millis=100001 -spring.datasource.druid.one.max-evictable-idle-time-millis=200001 -spring.datasource.druid.two.min-evictable-idle-time-millis=100002 -spring.datasource.druid.two.max-evictable-idle-time-millis=200002 \ No newline at end of file diff --git a/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/DruidAutoConfiguration.java b/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/DruidAutoConfiguration.java index fb77006..747a155 100644 --- a/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/DruidAutoConfiguration.java +++ b/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/DruidAutoConfiguration.java @@ -9,22 +9,34 @@ import com.alibaba.druid.filter.stat.StatFilter; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.wall.WallConfig; import com.alibaba.druid.wall.WallFilter; +import com.github.trang.druid.autoconfigure.datasource.DruidDataSource2; import com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.*; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.bind.PropertySourcesBinder; +import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.annotation.*; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Environment; +import org.springframework.core.type.AnnotatedTypeMetadata; + +import javax.sql.DataSource; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.*; @@ -39,7 +51,10 @@ import static com.github.trang.druid.autoconfigure.properties.DruidDataSourcePro @EnableConfigurationProperties({DataSourceProperties.class, DruidDataSourceProperties.class}) @Import({DruidServletConfiguration.class, DruidStatConfiguration.class}) @Slf4j -public class DruidAutoConfiguration implements InitializingBean { +public class DruidAutoConfiguration implements BeanFactoryAware, EnvironmentAware { + + private DefaultListableBeanFactory beanFactory; + private ConfigurableEnvironment environment; @Bean @ConditionalOnProperty(prefix = DRUID_STAT_FILTER_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true) @@ -105,39 +120,101 @@ public class DruidAutoConfiguration implements InitializingBean { return new CommonsLogFilter(); } - @Autowired - private DefaultListableBeanFactory beanFactory; - @Autowired - private ConfigurableEnvironment environment; - @Autowired - private DruidDataSourceProperties druidDataSourceProperties; + /** + * 自动注入单数据源 + * + * @condition 1. BeanFactory 中不存在 DruidDataSource 类型的 bean + * @condition 2. BeanFactory 中不存在 'dataSource' 名称的 bean + * @condition 3. 配置文件中不存在以 'spring.datasource.druid.data-source' 开头的属性 + * @return DruidDataSource dataSource + */ + @Bean(initMethod = "init", destroyMethod = "close") + @ConditionalOnMissingBean(value = DataSource.class, name = "dataSource") + @Conditional(DataSourceCondition.class) + public DruidDataSource dataSource() { + log.debug("druid data-source init..."); + return new DruidDataSource2(); + } - private static final String PRIMARY_DATA_SOURCE_NAME = "dataSource"; - private static final String DATA_SOURCE_NAME_SUFFIX = "DataSource"; + /** + * 自动注入多数据源 + * + * @condition 1. BeanFactory 中不存在 DruidDataSource 类型的 bean + * @condition 2. 配置文件中存在以 'spring.datasource.druid.data-source' 开头的属性 + * @return Map dataSourceMap/druidDataSourceMap + */ + @Bean + @Conditional(DataSourcesCondition.class) + public Map dataSourceMap(DruidDataSourceProperties druidDataSourceProperties) { + druidDataSourceProperties.getDataSources().forEach((dataSourceName, dataSourceConfig) -> { + // 构造 BeanDefinition,通过 DruidDataSource2 实现继承 'spring.datasource.druid' 的配置 + BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(DruidDataSource2.class) + .setInitMethodName("init") + .setDestroyMethodName("close") + .getBeanDefinition(); + // 注册 BeanDefinition + beanFactory.registerBeanDefinition(dataSourceName, beanDefinition); + // 注册 Alias + beanFactory.registerAlias(dataSourceName, dataSourceName + "DataSource"); + // 将 'spring.datasource.druid.data-sources.$dataSourceName' 的配置绑定到 Bean + DruidDataSource2 dataSource = beanFactory.getBean(dataSourceName, DruidDataSource2.class); + PropertySourcesBinder propertySourcesBinder = new PropertySourcesBinder(environment); + propertySourcesBinder.bindTo("spring.datasource.druid.data-sources." + dataSourceName, dataSource); + log.debug("druid {}-data-source init...", dataSourceName); + }); + return new HashMap<>(beanFactory.getBeansOfType(DruidDataSource2.class)); + } + + /** + * 为了便于使用,增加数据源集合,可直接注入使用 + * 如需使用 Set、Array 请注入 Set 或 DruidDataSource2[] + * + * @param dataSourceMap 多数据源 + * @return List dataSourceList + */ + @Bean + @ConditionalOnBean(name = "dataSourceMap") + @DependsOn("dataSourceMap") + public List dataSourceList(Map dataSourceMap) { + return new ArrayList<>(dataSourceMap.values()); + } + + static class DataSourceCondition extends SpringBootCondition { + + @Override + public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { + RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), "spring.datasource.druid."); + Map properties = resolver.getSubProperties("data-sources"); + if (!properties.isEmpty()) { + return ConditionOutcome.noMatch("find 'data-sources' properties"); + } + return ConditionOutcome.match(); + } + + } + + static class DataSourcesCondition extends SpringBootCondition { + + @Override + public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { + RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), "spring.datasource.druid."); + Map properties = resolver.getSubProperties("data-sources"); + if (properties.isEmpty()) { + return ConditionOutcome.noMatch("can't find 'data-sources' properties"); + } + return ConditionOutcome.match(); + } + + } @Override - public void afterPropertiesSet() throws Exception { -// if (druidDataSourceProperties.getDataSources().isEmpty() && !beanFactory.containsBean(PRIMARY_DATA_SOURCE_NAME)) { -// BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(DruidDataSource2.class) -// .setInitMethodName("init") -// .setDestroyMethodName("close") -// .getBeanDefinition(); -// beanFactory.registerBeanDefinition(PRIMARY_DATA_SOURCE_NAME, beanDefinition); -// log.debug("druid data-source init..."); -// } else { -// druidDataSourceProperties.getDataSources().forEach((dataSourceName, dataSourceConfig) -> { -// BeanDefinition eachBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(DruidDataSource2.class) -// .setInitMethodName("init") -// .setDestroyMethodName("close") -// .getBeanDefinition(); -// String beanName = dataSourceName + DATA_SOURCE_NAME_SUFFIX; -// beanFactory.registerBeanDefinition(beanName, eachBeanDefinition); -// DruidDataSource2 eachDataSource = beanFactory.getBean(beanName, DruidDataSource2.class); -// PropertySourcesBinder propertySourcesBinder = new PropertySourcesBinder(environment); -// propertySourcesBinder.bindTo("spring.datasource.druid.data-sources." + dataSourceName, eachDataSource); -// log.debug("druid {}-data-source init...", dataSourceName); -// }); -// } + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = (DefaultListableBeanFactory)beanFactory; + } + + @Override + public void setEnvironment(Environment environment) { + this.environment = (ConfigurableEnvironment)environment; } } \ No newline at end of file diff --git a/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/DruidDataSourceInitializerAutoConfiguration.java b/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/DruidDataSourceInitializerAutoConfiguration.java index 507330e..923e7e6 100644 --- a/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/DruidDataSourceInitializerAutoConfiguration.java +++ b/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/DruidDataSourceInitializerAutoConfiguration.java @@ -29,9 +29,7 @@ import javax.sql.DataSource; public class DruidDataSourceInitializerAutoConfiguration { @Bean - @ConditionalOnMissingBean( - type = "org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer", - value = DruidDataSourceInitializer.class) + @ConditionalOnMissingBean(value = DruidDataSourceInitializer.class, name = "dataSourceInitializer") public DruidDataSourceInitializer dataSourceInitializer(DataSourceProperties properties, ApplicationContext applicationContext) { return new DruidDataSourceInitializer(properties, applicationContext); diff --git a/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/datasource/DruidDataSource2.java b/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/datasource/DruidDataSource2.java index 3567e56..7783335 100644 --- a/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/datasource/DruidDataSource2.java +++ b/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/datasource/DruidDataSource2.java @@ -1,7 +1,7 @@ package com.github.trang.druid.autoconfigure.datasource; /** - * Druid 数据源,会继承 `spring.datasource.druid` 配置,并注入 `spring.datasource.druid.${name}` 配置 + * Druid 数据源,会继承 DruidDataSource2Support 的配置,并注入 'spring.datasource.druid.data-source.${name}' 的配置 * * @author trang */ diff --git a/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/datasource/DruidDataSource2Support.java b/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/datasource/DruidDataSource2Support.java index 4f41d5e..c4fb3d8 100644 --- a/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/datasource/DruidDataSource2Support.java +++ b/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/datasource/DruidDataSource2Support.java @@ -19,7 +19,7 @@ import java.util.Optional; import static com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.DRUID_DATA_SOURCE_PREFIX; /** - * Druid 多数据源支持,会自动注入 `spring.datasource.druid` 配置 + * Druid 多数据源支持,会自动注入 'spring.datasource' 和 'spring.datasource.druid' 配置 * * @author trang */ @@ -30,7 +30,7 @@ public abstract class DruidDataSource2Support extends DruidDataSource { private DataSourceProperties dataSourceProperties; @Autowired private DruidDataSourceProperties druidDataSourceProperties; - @Autowired + @Autowired(required = false) private List druidFilters; @PostConstruct diff --git a/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/properties/DruidDataSourceProperties.java b/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/properties/DruidDataSourceProperties.java index 5fb224a..a4a4b3e 100644 --- a/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/properties/DruidDataSourceProperties.java +++ b/druid-spring-boot/druid-spring-boot-autoconfigure/src/main/java/com/github/trang/druid/autoconfigure/properties/DruidDataSourceProperties.java @@ -28,11 +28,8 @@ public class DruidDataSourceProperties { public static final String DRUID_LOG4J_FILTER_PREFIX = "spring.datasource.druid.log4j"; public static final String DRUID_LOG4J2_FILTER_PREFIX = "spring.datasource.druid.log4j2"; public static final String DRUID_COMMONS_LOG_FILTER_PREFIX = "spring.datasource.druid.commons-log"; - public static final String DRUID_CONFIG_FILTER_PREFIX = "spring.datasource.druid.config"; - public static final String DRUID_STAT_VIEW_SERVLET_PREFIX = "spring.datasource.druid.stat-view-servlet"; - public static final String DRUID_WEB_STAT_PREFIX = "spring.datasource.druid.web-stat"; public static final String DRUID_AOP_STAT_PREFIX = "spring.datasource.druid.aop-stat";