This commit is contained in:
trang
2017-09-29 12:40:32 +08:00
parent 5a55a59baf
commit faa01757a6
35 changed files with 374 additions and 472 deletions
@@ -31,6 +31,11 @@
<artifactId>druid</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
@@ -4,14 +4,17 @@ import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* Druid Actuator 自动配置,默认开启
*
* @author trang
*/
@Configuration
@ConditionalOnClass(DruidDataSource.class)
@ConditionalOnProperty(prefix = "management.druid", name = "enabled", matchIfMissing = true)
//@Import({DruidDataSourceEndpointConfiguration.class, DruidDataSourceMetadataProviderConfiguration.class})
@ConditionalOnProperty(prefix = "management.druid", name = "enabled", havingValue = "true", matchIfMissing = true)
@Import({DruidDataSourceEndpointConfiguration.class, DruidDataSourceMetadataProviderConfiguration.class})
public class DruidDataSourceActuatorAutoConfiguration {
}
@@ -1,13 +1,31 @@
package com.github.trang.druid.actuate.autoconfigure;
import com.github.trang.druid.actuate.DruidDataSourceEndpoint;
import com.github.trang.druid.actuate.DruidDataSourceMvcEndpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Druid Endpoint & Druid MvcEndpoint 自动配置,默认开启
*
* @author trang
*/
@Configuration
@ConditionalOnProperty(prefix = "endpoints.druid", name = "enabled", havingValue = "true")
@ConditionalOnProperty(prefix = "endpoints.druid", name = "enabled", havingValue = "true", matchIfMissing = true)
public class DruidDataSourceEndpointConfiguration {
@Bean
@ConditionalOnMissingBean
public DruidDataSourceEndpoint druidDataSourceEndpoint() {
return new DruidDataSourceEndpoint();
}
@Bean
@ConditionalOnMissingBean
public DruidDataSourceMvcEndpoint druidDataSourceMvcEndpoint(DruidDataSourceEndpoint druidDataSourceEndpoint) {
return new DruidDataSourceMvcEndpoint(druidDataSourceEndpoint);
}
}
@@ -3,7 +3,6 @@ package com.github.trang.druid.actuate.autoconfigure;
import com.alibaba.druid.pool.DruidDataSource;
import com.github.trang.druid.actuate.DruidDataSourcePoolMetadata;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadata;
import org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvider;
@@ -13,10 +12,11 @@ import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
/**
* Druid Metadata 自动配置,适用于 Metrics,默认开启
*
* @author trang
*/
@Configuration
@ConditionalOnClass(DruidDataSource.class)
@ConditionalOnBean(DruidDataSource.class)
public class DruidDataSourceMetadataProviderConfiguration {
@@ -0,0 +1,24 @@
{
"groups": [
{
"name": "management.druid"
},
{
"name": "endpoints.druid"
}
],
"properties": [
{
"name": "management.druid.enabled",
"type": "java.lang.Boolean",
"description": "Whether or not druid actuator are enabled.",
"defaultValue": true
},
{
"name": "endpoints.druid.enabled",
"type": "java.lang.Boolean",
"description": "Whether or not druid endpoint are enabled.",
"defaultValue": false
}
]
}
@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.github.trang.druid.actuate.autoconfigure.DruidDataSourceActuatorAutoConfiguration
+4 -1
View File
@@ -20,7 +20,10 @@
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
@@ -1 +1 @@
provides: druid,druid-spring-boot-actuator,druid-spring-boot-actuator-autoconfigure,slf4j-api
provides: druid,druid-spring-boot-actuator,druid-spring-boot-actuator-autoconfigure,slf4j-api,lombok
+5
View File
@@ -17,6 +17,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
@@ -1,51 +1,29 @@
package com.github.trang.druid.actuate;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.stat.DruidStatManagerFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.Map;
/**
* 将 Druid 的信息暴露出来
*
* @author trang
*/
public class DruidDataSourceEndpoint extends AbstractEndpoint<Set<Health>> {
@ConfigurationProperties(prefix = "endpoints.druid")
public class DruidDataSourceEndpoint extends AbstractEndpoint<List<Map<String, Object>>> {
public DruidDataSourceEndpoint() {
super("druid");
}
@Autowired
private List<DruidDataSource> dataSourceList;
private static final DruidStatManagerFacade statManager = DruidStatManagerFacade.getInstance();
@Override
public Set<Health> invoke() {
if (dataSourceList == null || dataSourceList.isEmpty()) {
return Collections.singleton(Health.outOfService()
.withException(new IllegalStateException("Can not find bean with type 'DruidDataSource'!"))
.build());
}
DruidStatManagerFacade statManager = DruidStatManagerFacade.getInstance();
return statManager.getDataSourceStatDataList().stream()
.map(ds -> new Health.Builder(Status.UP, ds).build())
.collect(Collectors.toSet());
// return dataSourceList.stream()
// .map(DruidDataSource::getName)
// .map(statManager::getDruidDataSourceByName)
// .map(m -> new Health.Builder(Status.UP, m).build())
// .collect(Collectors.toSet());
// return dataSourceList.stream()
// .map(gson::toJson)
// .map(this::readValueAsMap)
// .map(m -> new Health.Builder(Status.UP, m).build())
// .collect(Collectors.toSet());
public List<Map<String, Object>> invoke() {
return statManager.getDataSourceStatDataList();
}
}
@@ -0,0 +1,54 @@
package com.github.trang.druid.actuate;
import com.alibaba.druid.stat.DruidStatService;
import org.springframework.boot.actuate.endpoint.mvc.ActuatorMediaTypes;
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
import org.springframework.boot.actuate.endpoint.mvc.HypermediaDisabled;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 将 {@link DruidDataSourceEndpoint} 适配成 {@link MvcEndpoint}
*
* @author trang
*/
@ConfigurationProperties(prefix = "endpoints.druid")
public class DruidDataSourceMvcEndpoint extends EndpointMvcAdapter {
private static final DruidStatService statService = DruidStatService.getInstance();
private final long timeout;
private final Lock lock = new ReentrantLock();
public DruidDataSourceMvcEndpoint(DruidDataSourceEndpoint delegate) {
super(delegate);
this.timeout = TimeUnit.SECONDS.toMillis(10);
}
public DruidDataSourceMvcEndpoint(DruidDataSourceEndpoint delegate, long timeout) {
super(delegate);
this.timeout = timeout;
}
@GetMapping(value = "/{name:.*}", produces = {ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE,
MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
@HypermediaDisabled
public String handle(@PathVariable String name) {
String temp = name;
if (name.contains(".")) {
temp = name.substring(0, name.indexOf("."));
}
name = "/" + temp + ".json";
return statService.service(name);
}
}
@@ -4,15 +4,12 @@ import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.autoconfigure.jdbc.metadata.AbstractDataSourcePoolMetadata;
/**
* Druid 的基础元数据
*
* @author trang
*/
public class DruidDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<DruidDataSource> {
/**
* Create an instance with the data source to use.
*
* @param dataSource the data source
*/
public DruidDataSourcePoolMetadata(DruidDataSource dataSource) {
super(dataSource);
}
+6 -1
View File
@@ -39,8 +39,13 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<optional>true</optional>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
@@ -1,4 +1,4 @@
package com.github.trang.druid;
package com.github.trang.druid.autoconfigure;
import com.alibaba.druid.filter.config.ConfigFilter;
import com.alibaba.druid.filter.logging.CommonsLogFilter;
@@ -9,11 +9,9 @@ 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.DruidStatConfiguration.DruidAopStatConfiguration;
import com.github.trang.druid.datasource.DruidParentDataSource;
import com.github.trang.druid.properties.DruidFilterProperties.DruidConfigFilterProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.trang.druid.autoconfigure.datasource.DruidDataSource2;
import com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -28,8 +26,7 @@ import org.springframework.context.annotation.Import;
import javax.sql.DataSource;
import static com.github.trang.druid.properties.DruidFilterProperties.DruidConfigFilterProperties.DRUID_CONFIG_FILTER_PREFIX;
import static com.github.trang.druid.properties.DruidProperties.*;
import static com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.*;
/**
* Druid 连接池的自动配置
@@ -39,12 +36,11 @@ import static com.github.trang.druid.properties.DruidProperties.*;
@Configuration
@ConditionalOnClass(DruidDataSource.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties({DataSourceProperties.class, DruidConfigFilterProperties.class})
@Import({DruidServletConfiguration.class, DruidAopStatConfiguration.class})
@EnableConfigurationProperties({DataSourceProperties.class, DruidDataSourceProperties.class})
@Import({DruidServletConfiguration.class, DruidStatConfiguration.class})
@Slf4j
public class DruidAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(DruidAutoConfiguration.class);
@Bean
@ConditionalOnProperty(prefix = DRUID_STAT_FILTER_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
@ConfigurationProperties(DRUID_STAT_FILTER_PREFIX)
@@ -113,7 +109,7 @@ public class DruidAutoConfiguration {
@ConditionalOnMissingBean(DataSource.class)
public DruidDataSource dataSource() {
log.debug("druid data-source init...");
return new DruidParentDataSource() {};
return new DruidDataSource2();
}
}
@@ -1,6 +1,6 @@
package com.github.trang.druid;
package com.github.trang.druid.autoconfigure;
import com.github.trang.druid.datasource.init.DruidDataSourceInitializer;
import com.github.trang.druid.autoconfigure.datasource.init.DruidDataSourceInitializer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -1,13 +1,13 @@
package com.github.trang.druid;
package com.github.trang.druid.autoconfigure;
import com.alibaba.druid.support.http.StatViewServlet;
import com.github.trang.druid.properties.DruidServletProperties.DruidStatViewServletProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties;
import com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.DruidStatViewServletProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -15,7 +15,8 @@ import org.springframework.util.StringUtils;
import javax.servlet.Servlet;
import static com.github.trang.druid.properties.DruidServletProperties.DRUID_STAT_VIEW_SERVLET_PREFIX;
import static com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.DRUID_STAT_VIEW_SERVLET_PREFIX;
/**
* Druid Servlet 配置
@@ -26,11 +27,9 @@ import static com.github.trang.druid.properties.DruidServletProperties.DRUID_STA
@ConditionalOnWebApplication
@ConditionalOnClass(Servlet.class)
@ConditionalOnProperty(prefix = DRUID_STAT_VIEW_SERVLET_PREFIX, name = "enabled", havingValue = "true")
@EnableConfigurationProperties(DruidStatViewServletProperties.class)
@Slf4j
public class DruidServletConfiguration {
private static final Logger log = LoggerFactory.getLogger(DruidServletConfiguration.class);
/**
* Druid 提供了一个 StatViewServlet 用于展示 Druid 的统计信息
* 这个 StatViewServlet 的用途包括:
@@ -38,8 +37,9 @@ public class DruidServletConfiguration {
* 2. 提供监控信息的 JSON API
*/
@Bean
public ServletRegistrationBean servletRegistrationBean(DruidStatViewServletProperties properties) {
public ServletRegistrationBean servletRegistrationBean(DruidDataSourceProperties druidDataSourceProperties) {
log.debug("druid stat-view-servlet init...");
DruidStatViewServletProperties properties = druidDataSourceProperties.getStatViewServlet();
ServletRegistrationBean registration = new ServletRegistrationBean();
StatViewServlet statViewServlet = new StatViewServlet();
registration.setServlet(statViewServlet);
@@ -1,19 +1,18 @@
package com.github.trang.druid;
package com.github.trang.druid.autoconfigure;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import com.github.trang.druid.properties.DruidStatProperties.DruidAopStatProperties;
import com.github.trang.druid.properties.DruidStatProperties.DruidWebStatProperties;
import com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties;
import com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.DruidAopStatProperties;
import com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.DruidWebStatProperties;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.aop.Advice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.aop.support.RegexpMethodPointcutAdvisor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -21,8 +20,8 @@ import org.springframework.util.StringUtils;
import javax.servlet.Filter;
import static com.github.trang.druid.properties.DruidStatProperties.DRUID_AOP_STAT_PREFIX;
import static com.github.trang.druid.properties.DruidStatProperties.DRUID_WEB_STAT_PREFIX;
import static com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.DRUID_AOP_STAT_PREFIX;
import static com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.DRUID_WEB_STAT_PREFIX;
/**
* Druid 监控配置
@@ -30,17 +29,15 @@ import static com.github.trang.druid.properties.DruidStatProperties.DRUID_WEB_ST
* @author trang
*/
@Configuration
@Slf4j
public class DruidStatConfiguration {
private static final Logger log = LoggerFactory.getLogger(DruidStatConfiguration.class);
/**
* 用于采集 Spring 和 JDBC 关联监控的数据
*/
@Configuration
@ConditionalOnClass(Advice.class)
@ConditionalOnProperty(prefix = DRUID_AOP_STAT_PREFIX, name = "enabled", havingValue = "true")
@EnableConfigurationProperties(DruidWebStatProperties.class)
public static class DruidAopStatConfiguration {
@Value("${spring.aop.proxy-target-class:false}")
@@ -52,8 +49,9 @@ public class DruidStatConfiguration {
}
@Bean
public RegexpMethodPointcutAdvisor druidStatAdvisor(DruidAopStatProperties properties,
public RegexpMethodPointcutAdvisor druidStatAdvisor(DruidDataSourceProperties druidDataSourceProperties,
DruidStatInterceptor druidStatInterceptor) {
DruidAopStatProperties properties = druidDataSourceProperties.getAopStat();
return new RegexpMethodPointcutAdvisor(properties.getPatterns(), druidStatInterceptor);
}
@@ -74,12 +72,12 @@ public class DruidStatConfiguration {
@ConditionalOnWebApplication
@ConditionalOnClass(Filter.class)
@ConditionalOnProperty(prefix = DRUID_WEB_STAT_PREFIX, name = "enabled", havingValue = "true")
@EnableConfigurationProperties(DruidAopStatProperties.class)
public static class DruidWebStatConfiguration {
@Bean
public FilterRegistrationBean filterRegistrationBean(DruidWebStatProperties properties) {
public FilterRegistrationBean filterRegistrationBean(DruidDataSourceProperties druidDataSourceProperties) {
log.debug("druid web-stat-filter init...");
DruidWebStatProperties properties = druidDataSourceProperties.getWebStat();
FilterRegistrationBean registration = new FilterRegistrationBean();
WebStatFilter filter = new WebStatFilter();
registration.setFilter(filter);
@@ -0,0 +1,10 @@
package com.github.trang.druid.autoconfigure.datasource;
/**
* Druid 数据源,会继承 `spring.datasource.druid` 配置,并注入 `spring.datasource.druid.${name}` 配置
*
* @author trang
*/
public class DruidDataSource2 extends DruidDataSource2Support {
}
@@ -1,15 +1,11 @@
package com.github.trang.druid.datasource;
package com.github.trang.druid.autoconfigure.datasource;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.FilterAdapter;
import com.alibaba.druid.filter.config.ConfigFilter;
import com.alibaba.druid.filter.logging.CommonsLogFilter;
import com.alibaba.druid.filter.logging.Log4j2Filter;
import com.alibaba.druid.filter.logging.Log4jFilter;
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 com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties;
import com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.DruidConfigFilterProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -18,9 +14,9 @@ import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import java.util.Optional;
import static com.github.trang.druid.properties.DruidProperties.DRUID_DATA_SOURCE_PREFIX;
import static com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.DRUID_DATA_SOURCE_PREFIX;
/**
* Druid 多数据源支持,会自动注入 `spring.datasource.druid` 配置
@@ -28,27 +24,14 @@ import static com.github.trang.druid.properties.DruidProperties.DRUID_DATA_SOURC
* @author trang
*/
@ConfigurationProperties(DRUID_DATA_SOURCE_PREFIX)
public abstract class DruidParentDataSource extends DruidDataSource {
public abstract class DruidDataSource2Support extends DruidDataSource {
@Autowired(required = false)
private StatFilter statFilter;
@Autowired(required = false)
private WallFilter wallFilter;
@Autowired(required = false)
private ConfigFilter configFilter;
@Autowired(required = false)
private Slf4jLogFilter slf4jLogFilter;
@Autowired(required = false)
private Log4jFilter log4jFilter;
@Autowired(required = false)
private Log4j2Filter log4j2Filter;
@Autowired(required = false)
private CommonsLogFilter commonsLogFilter;
// 不使用 @Value 注入,避免因为找不到值抛出 NPE
@Autowired
private DataSourceProperties dataSourceProperties;
@Autowired
private DruidConfigFilterProperties druidConfigFilterProperties;
private DruidDataSourceProperties druidDataSourceProperties;
@Autowired
private Optional<List<FilterAdapter>> druidFilters;
@PostConstruct
public void initDruidParentProperties() {
@@ -57,29 +40,6 @@ public abstract class DruidParentDataSource extends DruidDataSource {
initFilters();
}
private void initFilters() {
List<Filter> 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());
@@ -95,4 +55,28 @@ public abstract class DruidParentDataSource extends DruidDataSource {
}
}
private void initConfigFilterProperties() {
DruidConfigFilterProperties configFilterProperties = druidDataSourceProperties.getConfig();
if (configFilterProperties.isEnabled()) {
StringBuilder builder = new StringBuilder();
builder.append(ConfigFilter.CONFIG_DECRYPT).append("=").append("true").append(";");
if (!StringUtils.isEmpty(configFilterProperties.getKey())) {
builder.append(ConfigFilter.CONFIG_KEY).append("=").append(configFilterProperties.getKey());
builder.append(";");
}
if (!StringUtils.isEmpty(configFilterProperties.getFile())) {
builder.append(ConfigFilter.CONFIG_FILE).append("=").append(configFilterProperties.getFile());
}
super.setConnectionProperties(builder.toString());
}
}
private void initFilters() {
List<Filter> filters = super.getProxyFilters();
druidFilters.ifPresent(dfs -> dfs.stream()
.filter(Objects::nonNull)
.filter(filter -> !filters.contains(filter))
.forEach(filters::add));
}
}
@@ -1,5 +1,6 @@
package com.github.trang.druid.datasource.init;
package com.github.trang.druid.autoconfigure.datasource.init;
import com.github.trang.druid.autoconfigure.DruidDataSourceInitializerAutoConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
@@ -31,7 +32,7 @@ import java.util.List;
* @author Stephane Nicoll
* @author Kazuki Shimizu
* @since 1.1.0
* @see com.github.trang.druid.DruidDataSourceInitializerAutoConfiguration
* @see DruidDataSourceInitializerAutoConfiguration
*/
public class DruidDataSourceInitializer implements ApplicationListener<DataSourceInitializedEvent> {
@@ -0,0 +1,103 @@
package com.github.trang.druid.autoconfigure.properties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import static com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties.DRUID_DATA_SOURCE_PREFIX;
/**
* Druid 自定义配置
*
* @author trang
*/
@ConfigurationProperties(DRUID_DATA_SOURCE_PREFIX)
@Getter @Setter
public class DruidDataSourceProperties {
public static final String DRUID_DATA_SOURCE_PREFIX = "spring.datasource.druid";
public static final String DRUID_STAT_FILTER_PREFIX = "spring.datasource.druid.stat";
public static final String DRUID_WALL_FILTER_PREFIX = "spring.datasource.druid.wall";
public static final String DRUID_WALL_CONFIG_PREFIX = "spring.datasource.druid.wall.config";
public static final String DRUID_SLF4J_FILTER_PREFIX = "spring.datasource.druid.slf4j";
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";
@NestedConfigurationProperty
DruidConfigFilterProperties config = new DruidConfigFilterProperties();
@NestedConfigurationProperty
DruidStatViewServletProperties statViewServlet = new DruidStatViewServletProperties();
@NestedConfigurationProperty
DruidWebStatProperties webStat = new DruidWebStatProperties();
@NestedConfigurationProperty
DruidAopStatProperties aopStat = new DruidAopStatProperties();
@Getter@Setter
public static class DruidConfigFilterProperties {
// 是否开启 druid config-filter,默认否
private boolean enabled;
// 密钥地址
private String file;
// 加密密钥
private String key;
}
@Getter
@Setter
public static class DruidStatViewServletProperties {
// 是否开启 druid 的数据统计页面,默认否
private boolean enabled;
// servlet 的映射规则,默认访问 "http://xxx/druid/"
private String urlMappings = "/druid/*";
// druid 统计页面的登陆用户名
private String loginUsername;
// druid 统计页面的登陆密码
private String loginPassword;
// druid 统计页面的访问白名单,默认允许所有人访问
private String allow;
// druid 统计页面的访问黑名单,优先于白名单
private String deny;
// 是否允许清空统计数据,默认否
private boolean resetEnable;
}
@Getter
@Setter
public static class DruidWebStatProperties {
// 是否开启 web-jdbc 监控,默认否
private boolean enabled;
// 过滤器 url 的映射规则
private String urlPatterns = "/*";
// 过滤器 url 的排除规则
private String exclusions = "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*";
// 是否开启 session 统计,默认否
private boolean sessionStatEnable;
// session 统计的最大值,默认值 1000
private Integer sessionStatMaxCount = 1000;
// 配置当前 session 的用户
private String principalSessionName;
// 配置当前 cookie 的用户
private String principalCookieName;
// 是否开启监控单个 url 调用的 sql 列表,默认是
private boolean profileEnable = true;
}
@Getter
@Setter
public static class DruidAopStatProperties {
// 是否开启基于 aop 的监控,默认否
private boolean enabled;
// aop 拦截规则
private String[] patterns;
}
}
@@ -1,11 +0,0 @@
package com.github.trang.druid.datasource;
/**
* Druid 多数据源支持,会继承 `spring.datasource.druid` 配置,
* 并注入 `spring.datasource.druid.${name}` 配置
*
* @author trang
*/
public class DruidMultiDataSource extends DruidParentDataSource {
}
@@ -1,50 +0,0 @@
package com.github.trang.druid.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import static com.github.trang.druid.properties.DruidFilterProperties.DruidConfigFilterProperties.DRUID_CONFIG_FILTER_PREFIX;
/**
* Dubbo Filter 自定义配置
*
* @author trang
*/
public class DruidFilterProperties {
@ConfigurationProperties(DRUID_CONFIG_FILTER_PREFIX)
public static class DruidConfigFilterProperties {
public static final String DRUID_CONFIG_FILTER_PREFIX = "spring.datasource.druid.config";
private boolean enabled;
private String file;
private String key;
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
}
@@ -1,19 +0,0 @@
package com.github.trang.druid.properties;
/**
* Druid 自定义配置
*
* @author trang
*/
public class DruidProperties {
public static final String DRUID_DATA_SOURCE_PREFIX = "spring.datasource.druid";
public static final String DRUID_STAT_FILTER_PREFIX = "spring.datasource.druid.stat";
public static final String DRUID_WALL_FILTER_PREFIX = "spring.datasource.druid.wall";
public static final String DRUID_WALL_CONFIG_PREFIX = "spring.datasource.druid.wall.config";
public static final String DRUID_SLF4J_FILTER_PREFIX = "spring.datasource.druid.slf4j";
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";
}
@@ -1,95 +0,0 @@
package com.github.trang.druid.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Druid 数据展示配置
*
* @author trang
*/
public class DruidServletProperties {
public static final String DRUID_STAT_VIEW_SERVLET_PREFIX = "spring.datasource.druid.stat-view-servlet";
/**
* StatViewServlet 自定义配置
*
* @author trang
*/
@ConfigurationProperties(DRUID_STAT_VIEW_SERVLET_PREFIX)
public static class DruidStatViewServletProperties {
// 是否开启 Druid 的数据统计页面,默认否
private boolean enabled;
// Servlet 的映射规则,默认访问 "http://xxx/druid/"
private String urlMappings = "/druid/*";
// Druid 统计页面的登陆用户名
private String loginUsername;
// Druid 统计页面的登陆密码
private String loginPassword;
// Druid 统计页面的访问白名单,默认允许所有人访问
private String allow;
// Druid 统计页面的访问黑名单,优先于白名单
private String deny;
// 是否允许清空统计数据,默认否
private boolean resetEnable;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getUrlMappings() {
return urlMappings;
}
public void setUrlMappings(String urlMappings) {
this.urlMappings = urlMappings;
}
public String getLoginUsername() {
return loginUsername;
}
public void setLoginUsername(String loginUsername) {
this.loginUsername = loginUsername;
}
public String getLoginPassword() {
return loginPassword;
}
public void setLoginPassword(String loginPassword) {
this.loginPassword = loginPassword;
}
public String getAllow() {
return allow;
}
public void setAllow(String allow) {
this.allow = allow;
}
public String getDeny() {
return deny;
}
public void setDeny(String deny) {
this.deny = deny;
}
public boolean isResetEnable() {
return resetEnable;
}
public void setResetEnable(boolean resetEnable) {
this.resetEnable = resetEnable;
}
}
}
@@ -1,135 +0,0 @@
package com.github.trang.druid.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Druid 监控配置
*
* @author trang
*/
public class DruidStatProperties {
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";
/**
* WebStat 自定义配置
*
* @author trang
*/
@ConfigurationProperties(DRUID_WEB_STAT_PREFIX)
public static class DruidWebStatProperties {
// 是否开启 web-jdbc 监控,默认否
private boolean enabled;
// 过滤器 url 的映射规则
private String urlPatterns = "/*";
// 过滤器 url 的排除规则
private String exclusions = "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*";
// 是否开启 session 统计,默认否
private boolean sessionStatEnable;
// session 统计的最大值,默认值 1000
private Integer sessionStatMaxCount = 1000;
// 配置当前 session 的用户
private String principalSessionName;
// 配置当前 cookie 的用户
private String principalCookieName;
// 是否开启监控单个 url 调用的 sql 列表,默认是
private boolean profileEnable = true;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getUrlPatterns() {
return urlPatterns;
}
public void setUrlPatterns(String urlPatterns) {
this.urlPatterns = urlPatterns;
}
public String getExclusions() {
return exclusions;
}
public void setExclusions(String exclusions) {
this.exclusions = exclusions;
}
public boolean isSessionStatEnable() {
return sessionStatEnable;
}
public void setSessionStatEnable(boolean sessionStatEnable) {
this.sessionStatEnable = sessionStatEnable;
}
public Integer getSessionStatMaxCount() {
return sessionStatMaxCount;
}
public void setSessionStatMaxCount(Integer sessionStatMaxCount) {
this.sessionStatMaxCount = sessionStatMaxCount;
}
public String getPrincipalSessionName() {
return principalSessionName;
}
public void setPrincipalSessionName(String principalSessionName) {
this.principalSessionName = principalSessionName;
}
public String getPrincipalCookieName() {
return principalCookieName;
}
public void setPrincipalCookieName(String principalCookieName) {
this.principalCookieName = principalCookieName;
}
public boolean isProfileEnable() {
return profileEnable;
}
public void setProfileEnable(boolean profileEnable) {
this.profileEnable = profileEnable;
}
}
/**
* Aop 监控自定义配置
*/
@ConfigurationProperties(DRUID_AOP_STAT_PREFIX)
public static class DruidAopStatProperties {
// 是否开启基于 aop 的监控,默认否
private boolean enabled;
// aop 拦截规则
private String[] patterns;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String[] getPatterns() {
return patterns;
}
public void setPatterns(String[] patterns) {
this.patterns = patterns;
}
}
}
@@ -46,21 +46,21 @@
"name": "spring.datasource.druid.aop-stat.enabled",
"type": "java.lang.Boolean",
"description": "Whether or not druid aop-stat are enabled.",
"sourceType": "com.github.trang.druid.properties.DruidStatProperties$DruidAopStatProperties",
"sourceType": "com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties$DruidAopStatProperties",
"defaultValue": false
},
{
"name": "spring.datasource.druid.web-stat.enabled",
"type": "java.lang.Boolean",
"description": "Whether or not druid web-stat are enabled.",
"sourceType": "com.github.trang.druid.properties.DruidStatProperties$DruidWebStatProperties",
"sourceType": "com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties$DruidWebStatProperties",
"defaultValue": false
},
{
"name": "spring.datasource.druid.stat-view-servlet.enabled",
"type": "java.lang.Boolean",
"description": "Whether or not druid stat-view-servlet are enabled.",
"sourceType": "com.github.trang.druid.properties.DruidServletProperties$DruidStatViewServletProperties",
"sourceType": "com.github.trang.druid.autoconfigure.properties.DruidDataSourceProperties$DruidStatViewServletProperties",
"defaultValue": false
}
],
@@ -1,3 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.github.trang.druid.DruidAutoConfiguration,\
com.github.trang.druid.DruidDataSourceInitializerAutoConfiguration
com.github.trang.druid.autoconfigure.DruidAutoConfiguration,\
com.github.trang.druid.autoconfigure.DruidDataSourceInitializerAutoConfiguration
+4
View File
@@ -47,6 +47,10 @@
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
@@ -29,7 +29,8 @@ public class DruidSpringBootStarterApplication implements CommandLineRunner {
public void run(String... args) throws Exception {
Gson gson = new Gson();
cityMapper.findAll().stream()
.map(gson::toJson).forEach(System.out::println);
.map(gson::toJson)
.forEach(System.out::println);
}
}
@@ -1,9 +1,8 @@
package com.github.trang.druid.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.github.trang.druid.datasource.DruidMultiDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.trang.druid.autoconfigure.datasource.DruidDataSource2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -21,12 +20,11 @@ import java.util.Map;
*/
@Configuration
@Profile({"dynamic", "dynamic-dev-yaml", "dynamic-dev-props"})
@Slf4j
public class SpringDataSourceConfig {
private static final Logger log = LoggerFactory.getLogger(SpringDataSourceConfig.class);
/**
* 第一个数据源,注意数据源类型为 #{@link com.github.trang.druid.datasource.DruidMultiDataSource}
* 第一个数据源,注意数据源类型为 #{@link DruidDataSource2}
*
* `spring.datasource.druid.one` 前缀的配置会注入到该 Bean,同时会继承 `spring.datasource.druid`
* 前缀的配置,若名称相同则会被 `spring.datasource.druid.one` 覆盖
@@ -35,7 +33,7 @@ public class SpringDataSourceConfig {
@ConfigurationProperties("spring.datasource.druid.one")
public DruidDataSource firstDataSource() {
log.debug("druid first-data-source init...");
return new DruidMultiDataSource();
return new DruidDataSource2();
}
/**
@@ -45,7 +43,7 @@ public class SpringDataSourceConfig {
@ConfigurationProperties("spring.datasource.druid.two")
public DruidDataSource secondDataSource() {
log.debug("druid second-data-source init...");
return new DruidMultiDataSource();
return new DruidDataSource2();
}
@Bean
@@ -22,7 +22,7 @@ spring:
password: Biyu5YzU+6sxDRbmWEa3B2uUcImzDo0BuXjTlL505+/pTb+/0Oqd3ou1R6J8+9Fy3CYrM18nBDqf6wAaPgUGOg==
schema: classpath:/import.sql
druid:
# spring.datasource.druid 前缀的配置将注入到 DruidParentDataSource,作为公共参数
# spring.datasource.druid 前缀的配置将注入到 DruidDataSource2Support,作为公共参数
initial-size: 1
min-idle: 1
max-active: 10
@@ -78,7 +78,7 @@ spring:
encoding:
force: true
converters:
preferred-json-mapper: gson
preferred-json-mapper: jackson
mybatis:
type-aliases-package: com.github.trang.druid.model
@@ -87,6 +87,23 @@ mybatis:
debug: false
spring:
profiles: actuator
management:
security:
enabled: false
endpoints:
actuator:
enabled: true
druid:
enabled: true
---
debug: false
spring:
profiles: default
+6 -2
View File
@@ -17,6 +17,10 @@
<groupId>com.github.drtrang</groupId>
<artifactId>druid-spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
@@ -26,8 +30,8 @@
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
@@ -1 +1 @@
provides: druid,druid-spring-boot-autoconfigure,spring-boot-autoconfigure,spring-jdbc
provides: druid,druid-spring-boot-autoconfigure,spring-boot-autoconfigure,spring-jdbc,slf4j-api,lombok
+10 -8
View File
@@ -52,15 +52,17 @@
<mybatis-spring-boot-starter.version>1.3.1</mybatis-spring-boot-starter.version>
<spring-boot.version>1.5.7.RELEASE</spring-boot.version>
<!-- Maven 插件 -->
<maven-dependency-plugin.version>3.0.1</maven-dependency-plugin.version>
<maven-dependency-plugin.version>3.0.2</maven-dependency-plugin.version>
<maven-clean-plugin.version>3.0.0</maven-clean-plugin.version>
<maven-resources-plugin.version>3.0.2</maven-resources-plugin.version>
<maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>
<maven-enforcer-plugin.version>1.4.1</maven-enforcer-plugin.version>
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
<!--<maven-enforcer-plugin.version>1.4.1</maven-enforcer-plugin.version>-->
<maven-enforcer-plugin.version>3.0.0-M1</maven-enforcer-plugin.version>
<maven-surefire-plugin.version>2.20.1</maven-surefire-plugin.version>
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
<maven-javadoc-plugin.version>2.10.4</maven-javadoc-plugin.version>
<!--<maven-javadoc-plugin.version>2.10.4</maven-javadoc-plugin.version>-->
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<maven-install-plugin.version>2.5.2</maven-install-plugin.version>
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<maven-release-plugin.version>2.5.3</maven-release-plugin.version>
@@ -147,6 +149,7 @@
<inherited>true</inherited>
<configuration>
<skip>true</skip>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
@@ -196,7 +199,7 @@
</execution>
</executions>
<configuration>
<encoding>UTF-8</encoding>
<encoding>${project.build.sourceEncoding}</encoding>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
</plugin>
@@ -238,8 +241,6 @@
</profiles>
<build>
<finalName>${project.artifactId}</finalName>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
@@ -277,6 +278,7 @@
<inherited>true</inherited>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<detail>true</detail>
</configuration>
</plugin>
<plugin>