mirror of
https://github.com/drtrang/druid-spring-boot.git
synced 2026-11-03 16:03:42 +00:00
1.1.3
This commit is contained in:
+2
-2
@@ -97,10 +97,10 @@ spring:
|
||||
druid:
|
||||
# 继承 spring.datasource.druid 前缀的配置,同时可以自定义配置,若名称相同则覆盖父配置
|
||||
data-sources:
|
||||
master-data-source:
|
||||
master:
|
||||
max-active: 50
|
||||
max-open-prepared-statements: 50
|
||||
slave-data-source:
|
||||
slave:
|
||||
max-active: 25
|
||||
max-open-prepared-statements: 25
|
||||
|
||||
|
||||
+3
-17
@@ -56,23 +56,9 @@ public class NormalTest {
|
||||
|
||||
@Test
|
||||
public void hashcode() {
|
||||
Hash hash = new Hash();
|
||||
Hash hash2 = new Hash();
|
||||
System.out.println(hash == hash2);
|
||||
System.out.println(hash.equals(hash2));
|
||||
String camelAlias = "XxXDatasource";
|
||||
String alias = camelAlias.substring(0, camelAlias.toLowerCase().indexOf("DataSource".toLowerCase()));
|
||||
System.out.println(alias);
|
||||
}
|
||||
|
||||
class Hash {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+29
@@ -9,9 +9,12 @@ 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.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
@@ -20,8 +23,14 @@ 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.DependsOn;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
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.*;
|
||||
|
||||
/**
|
||||
@@ -101,4 +110,24 @@ public class DruidAutoConfiguration {
|
||||
return new CommonsLogFilter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(DruidDataSource.class)
|
||||
public Map<String, DruidDataSource> dataSourceMap(ConfigurableListableBeanFactory beanFactory) {
|
||||
return new HashMap<>(beanFactory.getBeansOfType(DruidDataSource2.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* 为了便于使用,增加数据源集合,可直接注入使用
|
||||
* 如需使用 Set、Array 请注入 Set<DruidDataSource2> 或 DruidDataSource2[]
|
||||
*
|
||||
* @param dataSourceMap 多数据源
|
||||
* @return List<DruidDataSource> dataSourceList
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnBean(name = "dataSourceMap")
|
||||
@DependsOn("dataSourceMap")
|
||||
public List<DruidDataSource> dataSourceList(Map<String, DruidDataSource> dataSourceMap) {
|
||||
return new ArrayList<>(dataSourceMap.values());
|
||||
}
|
||||
|
||||
}
|
||||
+96
-44
@@ -1,22 +1,21 @@
|
||||
package com.github.trang.druid.autoconfigure;
|
||||
|
||||
import com.github.trang.druid.autoconfigure.datasource.DruidDataSource2;
|
||||
import com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties;
|
||||
import com.github.trang.druid.autoconfigure.util.CharMatcher;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import com.github.trang.druid.autoconfigure.DruidDataSourceConfiguration.DataSourceImportSelector;
|
||||
import com.github.trang.druid.autoconfigure.datasource.DruidDataSource2;
|
||||
import com.github.trang.druid.autoconfigure.util.CharMatcher;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.bind.PropertySourcesBinder;
|
||||
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.context.annotation.*;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
@@ -24,18 +23,25 @@ import org.springframework.core.type.AnnotationMetadata;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Druid 数据源配置
|
||||
*
|
||||
* @author trang
|
||||
*/
|
||||
@Import({DataSourceImportSelector.class})
|
||||
@Import(DataSourceImportSelector.class)
|
||||
@Slf4j
|
||||
public class DruidDataSourceConfiguration {
|
||||
|
||||
public static class SingleDataSourceRegister implements ImportBeanDefinitionRegistrar {
|
||||
/**
|
||||
* 单数据源注册
|
||||
*
|
||||
* @author trang
|
||||
*/
|
||||
static class SingleDataSourceRegister implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
static final String BEAN_NAME = "dataSource";
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
||||
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
|
||||
if (!registry.containsBeanDefinition(BEAN_NAME)) {
|
||||
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(DruidDataSource2.class)
|
||||
.setInitMethodName("init")
|
||||
@@ -47,48 +53,62 @@ public class DruidDataSourceConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
public static class DynamicDataSourceRegister implements ImportBeanDefinitionRegistrar, BeanFactoryAware, EnvironmentAware {
|
||||
/**
|
||||
* 多数据源注册
|
||||
*
|
||||
* @author trang
|
||||
*/
|
||||
static class DynamicDataSourceRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware {
|
||||
|
||||
private DruidDataSourceProperties druidDataSourceProperties;
|
||||
private DefaultListableBeanFactory beanFactory;
|
||||
private ConfigurableEnvironment environment;
|
||||
private static final String BEAN_SUFFIX = "DataSource";
|
||||
private RelaxedPropertyResolver resolver;
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
||||
druidDataSourceProperties.getDataSources().forEach((dataSourceName, dataSourceConfig) -> {
|
||||
// 构造 BeanDefinition,通过 DruidDataSource2 实现继承 'spring.datasource.druid' 的配置
|
||||
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(DruidDataSource2.class)
|
||||
.setInitMethodName("init")
|
||||
.setDestroyMethodName("close")
|
||||
.getBeanDefinition();
|
||||
// 注册 BeanDefinition
|
||||
String beanName = CharMatcher.separatedToCamel().apply(dataSourceName);
|
||||
registry.registerBeanDefinition(beanName, beanDefinition);
|
||||
// 将 'spring.datasource.druid.data-sources.${name}' 的配置绑定到 Bean
|
||||
DruidDataSource2 dataSource = beanFactory.getBean(beanName, DruidDataSource2.class);
|
||||
PropertySourcesBinder propertySourcesBinder = new PropertySourcesBinder(environment);
|
||||
propertySourcesBinder.bindTo("spring.datasource.druid.data-sources." + dataSourceName, dataSource);
|
||||
log.debug("druid {}-data-source init...", dataSourceName);
|
||||
});
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setDruidDataSourceProperties(DruidDataSourceProperties properties) {
|
||||
this.druidDataSourceProperties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = (DefaultListableBeanFactory) beanFactory;
|
||||
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
|
||||
resolver.getSubProperties("").keySet().stream()
|
||||
.map(key -> key.substring(0, key.indexOf(".")))
|
||||
.distinct()
|
||||
.forEach(dataSourceName -> {
|
||||
// 构造 BeanDefinition,通过 DruidDataSource2 实现继承 'spring.datasource.druid' 的配置
|
||||
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(DruidDataSource2.class)
|
||||
.setInitMethodName("init")
|
||||
.setDestroyMethodName("close")
|
||||
.getBeanDefinition();
|
||||
// 注册 BeanDefinition
|
||||
registry.registerBeanDefinition(dataSourceName, beanDefinition);
|
||||
// 注册驼峰别名
|
||||
String camelAlias = CharMatcher.separatedToCamel().apply(dataSourceName);
|
||||
registry.registerAlias(dataSourceName, camelAlias);
|
||||
// 注册以 DataSource 为后缀的别名
|
||||
String otherAlias;
|
||||
if (camelAlias.toLowerCase().endsWith(BEAN_SUFFIX.toLowerCase())) {
|
||||
if (!camelAlias.endsWith(BEAN_SUFFIX)) {
|
||||
otherAlias = camelAlias.substring(0, camelAlias.toLowerCase().indexOf(BEAN_SUFFIX.toLowerCase()));
|
||||
otherAlias = otherAlias + BEAN_SUFFIX;
|
||||
registry.registerAlias(dataSourceName, otherAlias);
|
||||
}
|
||||
} else {
|
||||
otherAlias = camelAlias + BEAN_SUFFIX;
|
||||
registry.registerAlias(dataSourceName, otherAlias);
|
||||
}
|
||||
log.debug("druid {}-data-source init...", dataSourceName);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = (ConfigurableEnvironment) environment;
|
||||
this.resolver = new RelaxedPropertyResolver(environment, "spring.datasource.druid.data-sources.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据源选择器
|
||||
* 当配置文件中存在 spring.datasource.druid.data-sources 属性时为多数据源
|
||||
* 不存在则为单数据源
|
||||
*
|
||||
* @author trang
|
||||
*/
|
||||
static class DataSourceImportSelector implements ImportSelector, EnvironmentAware {
|
||||
|
||||
private ConfigurableEnvironment environment;
|
||||
@@ -98,9 +118,41 @@ public class DruidDataSourceConfiguration {
|
||||
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment, "spring.datasource.druid.");
|
||||
Map<String, Object> properties = resolver.getSubProperties("data-sources");
|
||||
if (properties.isEmpty()) {
|
||||
return new String[]{DruidDataSourceProperties.class.getName(), SingleDataSourceRegister.class.getName()};
|
||||
return new String[]{SingleDataSourceRegister.class.getName()};
|
||||
}
|
||||
return new String[]{DruidDataSourceProperties.class.getName(), DynamicDataSourceRegister.class.getName()};
|
||||
return new String[]{DynamicDataSourceRegister.class.getName(),
|
||||
DataSourceBeanPostProcessor.class.getName()};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = (ConfigurableEnvironment) environment;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* DataSource Bean 处理器
|
||||
*
|
||||
* @author trang
|
||||
*/
|
||||
static class DataSourceBeanPostProcessor implements BeanPostProcessor, EnvironmentAware {
|
||||
|
||||
private ConfigurableEnvironment environment;
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof DruidDataSource) {
|
||||
// 将 'spring.datasource.druid.data-sources.${name}' 的配置绑定到 Bean
|
||||
PropertySourcesBinder binder = new PropertySourcesBinder(environment);
|
||||
binder.bindTo("spring.datasource.druid.data-sources." + beanName, bean);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
@@ -18,6 +18,10 @@ public final class CharMatcher {
|
||||
return Manipulation.SEPARATED_TO_CAMELCASE;
|
||||
}
|
||||
|
||||
public static Manipulation camelToHyphen() {
|
||||
return Manipulation.CAMELCASE_TO_HYPHEN;
|
||||
}
|
||||
|
||||
public static enum Manipulation {
|
||||
|
||||
NONE {
|
||||
|
||||
Reference in New Issue
Block a user