Merge pull request #1705 from lihengming/master

add druid-spring-boot-autoconfigure support
This commit is contained in:
高铁
2017-05-16 15:55:50 +08:00
committed by GitHub
23 changed files with 883 additions and 193 deletions
+25
View File
@@ -0,0 +1,25 @@
target/
!.mvn/wrapper/maven-wrapper.jar
*.db
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
+87 -22
View File
@@ -1,35 +1,100 @@
druid-spring-boot-start
=======================
Spring boot with druid support。
# Druid Spring Boot Starter
Spring Boot with Druid support,help you simplify Druid config in Spring Boot.
### 如何使用
在Spring Boot项目的pom.xml中添加以下依赖:
```xml
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.0.29-SNAPSHOT</version>
</dependency>
```
Druid的连接池配置采用Spring Boot标准的数据库连接池配置方式,配置按照标准设置即可。
### 配置项
Druid Spring Boot Starter 配置项参数名称完全遵照Druid,你可以通过自定义配置去覆盖默认值。
```xml
# JDCB配置,参考Spring Boot文档该部分
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=
```properties
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/druid
spring.datasource.username=root
spring.datasource.password=123456
```
#连接池配置,说明请参考Druid Wiki,配置_DruidDataSource参考配置
spring.datasource.druid.filters= #默认值为stat,配置多个请以英文逗号分隔,如stat,wall,log4j
spring.datasource.druid.initialSize=
spring.datasource.druid.minIdle=
spring.datasource.druid.maxActive=
spring.datasource.druid.maxWait=
spring.datasource.druid.timeBetweenEvictionRunsMillis=
spring.datasource.druid.minEvictableIdleTimeMillis=
spring.datasource.druid.validationQuery=
spring.datasource.druid.testWhileIdle=
spring.datasource.druid.testOnBorrow=
spring.datasource.druid.testOnReturn=
spring.datasource.druid.poolPreparedStatements=
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=
... Druid Spring Boot Starter不仅限于对以上配置项的支持,DruidDataSource提供set方法的属性都可在此进行配置,但需自行检查。
如果你想设置druid的具体参数,请参考 spring.datasource.druid.* 下的具体配置项。
#WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter
spring.datasource.druid.WebStatFilter.enabled= #是否启用StatFilter默认值true
spring.datasource.druid.WebStatFilter.urlPattern=
spring.datasource.druid.WebStatFilter.exclusions=
spring.datasource.druid.WebStatFilter.sessionStatMaxCount=
spring.datasource.druid.WebStatFilter.sessionStatEnable=
spring.datasource.druid.WebStatFilter.principalSessionName=
spring.datasource.druid.WebStatFilter.principalCookieName=
spring.datasource.druid.WebStatFilter.profileEnable=
#StatViewServlet配置,说明请参考Druid Wiki,配置_StatViewServlet配置
spring.datasource.druid.StatViewServlet.enabled= #是否启用StatViewServlet默认值true
spring.datasource.druid.StatViewServlet.urlPattern=
spring.datasource.druid.StatViewServlet.resetEnable=
spring.datasource.druid.StatViewServlet.loginUsername=
spring.datasource.druid.StatViewServlet.loginPassword=
spring.datasource.druid.StatViewServlet.allow=
spring.datasource.druid.StatViewServlet.deny=
### Todo
#Spring监控配置,说明请参考Druid Github Wiki,配置_配置WebStatFilter
spring.datasource.druid.aop-patterns= #Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
#如果spring.datasource.druid.aop-patterns要代理的类没有定义interface请设置spring.aop.proxy-target-class=true
```
### 如何配置多数据源
添加数据源配置
```xml
spring.datasource.druid.one.url=
spring.datasource.druid.one.username=
spring.datasource.druid.one.password=
spring.datasource.druid.one.driver-class-name=
spring.datasource.druid.one.maxActive=
...
* stat view servlet调整到management port上,这样可以解决安全问题
* stat拦截中未考虑SEO的情况,如果在SEO的情况下,会导致URL数量暴增,如aliexpress的商品详情URL
spring.datasource.druid.two.url=
spring.datasource.druid.two.username=
spring.datasource.druid.two.password=
spring.datasource.druid.two.driver-class-name=
spring.datasource.druid.two.maxActive=
...
```
使用```DruidDataSourceBuilder```创建数据源
```java
@Primary
@ConfigurationProperties("spring.datasource.druid.one")
@Bean
public DataSource dataSource(){
return DruidDataSourceBuilder.create().build();
}
@ConfigurationProperties("spring.datasource.druid.two")
@Bean
public DataSource dataSourceTwo(){
return DruidDataSourceBuilder.create().build();
}
```
### 参考文档
### 演示
克隆项目,运行```test```包内的```DemoApplication```。
### 参考
[Druid Wiki](https://github.com/alibaba/druid/wiki/%E9%A6%96%E9%A1%B5)
* Spring Boot多数据源:http://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html
* Druid Wiki: https://github.com/alibaba/druid/wiki
[Spring Boot Reference](http://docs.spring.io/spring-boot/docs/1.5.1.RELEASE/reference/html/)
+124 -59
View File
@@ -2,77 +2,25 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.alibaba.boot</groupId>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>5.1.26-SNAPSHOT</version>
<version>1.0.29-SNAPSHOT</version>
<packaging>jar</packaging>
<name>tddl-spring-boot-starter</name>
<url>http://gitlab.alibaba-inc.com/sping-boot/tddl-spring-boot-starter</url>
<name>druid-spring-boot-starter</name>
<properties>
<spring-boot.version>1.4.5.RELEASE</spring-boot.version>
<druid.version>1.0.29</druid.version>
<spring-boot.version>1.5.3.RELEASE</spring-boot.version>
</properties>
<developers>
<developer>
<id>leijuan</id>
<name>雷卷</name>
<email>jacky.chenlb@alibaba-inc.com</email>
<url>https://work.alibaba-inc.com/work/u/7883</url>
<roles>
<role>开发人员</role>
</roles>
<name>李恒名</name>
<url>https://github.com/lihengming/</url>
<email>89921218@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:git@gitlab.alibaba-inc.com:spring-boot-incubator/druid-spring-boot-starter.git</connection>
<developerConnection>scm:git:git@gitlab.alibaba-inc.com:spring-boot-incubator/druid-spring-boot-starter.git
</developerConnection>
<url>http://gitlab.alibaba-inc.com/spring-boot-incubator/druid-spring-boot-starter</url>
</scm>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
@@ -87,4 +35,121 @@
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- @ConfigurationProperties annotation processing (metadata for IDEs) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<scm>
<connection>scm:git:git@gitlab.alibaba-inc.com:spring-boot-incubator/druid-spring-boot-starter.git</connection>
<developerConnection>scm:git:git@gitlab.alibaba-inc.com:spring-boot-incubator/druid-spring-boot-starter.git
</developerConnection>
<url>http://gitlab.alibaba-inc.com/spring-boot-incubator/druid-spring-boot-starter</url>
</scm>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>releases</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<downloadUrl>https://oss.sonatype.org/content/groups/public</downloadUrl>
</distributionManagement>
</project>
@@ -0,0 +1,69 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.spring.boot.autoconfigure;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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.core.env.Environment;
import javax.sql.DataSource;
import java.sql.SQLException;
/**
* @author lihengming<89921218@qq.com>
*/
@Configuration
@ConditionalOnClass(com.alibaba.druid.pool.DruidDataSource.class)
@EnableConfigurationProperties(DruidStatProperties.class)
@Import({DruidSpringAopConfiguration.class, DruidStatViewServletConfiguration.class, DruidWebStatFilterConfiguration.class})
public class DruidDataSourceAutoConfigure {
@Bean
@ConfigurationProperties("spring.datasource.druid")
@ConditionalOnMissingBean
public DataSource dataSource(Environment env) {
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
//if not found prefix 'spring.datasource.druid' settings,'spring.datasource' prefix settings will be used.
if (dataSource.getUsername() == null) {
dataSource.setUsername(env.getProperty("spring.datasource.username"));
}
if (dataSource.getPassword() == null) {
dataSource.setPassword(env.getProperty("spring.datasource.password"));
}
if (dataSource.getUrl() == null) {
dataSource.setUrl(env.getProperty("spring.datasource.url"));
}
if (dataSource.getDriverClassName() == null) {
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
}
// set filters default value on StatViewServlet enabled.
if (! "false".equals(env.getProperty("spring.datasource.druid.StatViewServlet.enabled"))) {
try {
dataSource.setFilters("stat");
} catch (SQLException e) {
e.printStackTrace();
}
}
return dataSource;
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.spring.boot.autoconfigure;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.jdbc.DatabaseDriver;
import java.util.HashMap;
import java.util.Map;
/**
* @author lihengming<89921218@qq.com>
*/
public class DruidDataSourceBuilder {
private Map<String, String> properties = new HashMap<String, String>();
public static DruidDataSourceBuilder create() {
return new DruidDataSourceBuilder();
}
public DruidDataSource build() {
DruidDataSource dataSource = new DruidDataSource();
maybeGetDriverClassName();
bind(dataSource);
return dataSource;
}
//use spring boot relaxed binding by reflection config druid . detail see Spring Boot Reference Relaxed binding section.
private void bind(DruidDataSource result) {
MutablePropertyValues properties = new MutablePropertyValues(this.properties);
new RelaxedDataBinder(result)
.withAlias("url", "jdbcUrl")
.withAlias("username", "user")
.bind(properties);
}
private void maybeGetDriverClassName() {
if (!this.properties.containsKey("driverClassName")
&& this.properties.containsKey("url")) {
String url = this.properties.get("url");
String driverClass = DatabaseDriver.fromJdbcUrl(url).getDriverClassName();
this.properties.put("driverClassName", driverClass);
}
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.spring.boot.autoconfigure;
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
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.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
/**
* @author lihengming<89921218@qq.com>
*/
@ConditionalOnProperty("spring.datasource.druid.aop-patterns")
public class DruidSpringAopConfiguration {
@Value("${spring.aop.proxy-target-class:false}")
private boolean proxyTargetClass;
@Bean
public Advice advice() {
return new DruidStatInterceptor();
}
@Bean
public Advisor advisor(DruidStatProperties properties) {
return new RegexpMethodPointcutAdvisor(properties.getAopPatterns(), advice());
}
@Bean
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(proxyTargetClass);
return advisorAutoProxyCreator;
}
}
@@ -0,0 +1,176 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.spring.boot.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author lihengming<89921218@qq.com>
*/
@ConfigurationProperties("spring.datasource.druid")
public class DruidStatProperties {
private String[] aopPatterns;
private StatViewServlet statViewServlet = new StatViewServlet();
private StatFilter statFilter = new StatFilter();
public String[] getAopPatterns() {
return aopPatterns;
}
public void setAopPatterns(String[] aopPatterns) {
this.aopPatterns = aopPatterns;
}
public StatViewServlet getStatViewServlet() {
return statViewServlet;
}
public void setStatViewServlet(StatViewServlet statViewServlet) {
this.statViewServlet = statViewServlet;
}
public StatFilter getStatFilter() {
return statFilter;
}
public void setStatFilter(StatFilter statFilter) {
this.statFilter = statFilter;
}
public static class StatViewServlet {
private String urlPattern;
private String allow;
private String deny;
private String loginUsername;
private String loginPassword;
private String resetEnable;
public String getUrlPattern() {
return urlPattern;
}
public void setUrlPattern(String urlPattern) {
this.urlPattern = urlPattern;
}
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 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 getResetEnable() {
return resetEnable;
}
public void setResetEnable(String resetEnable) {
this.resetEnable = resetEnable;
}
}
public static class StatFilter {
private String urlPattern;
private String exclusions;
private String sessionStatMaxCount;
private String sessionStatEnable;
private String principalSessionName;
private String principalCookieName;
private String profileEnable;
public String getUrlPattern() {
return urlPattern;
}
public void setUrlPattern(String urlPattern) {
this.urlPattern = urlPattern;
}
public String getExclusions() {
return exclusions;
}
public void setExclusions(String exclusions) {
this.exclusions = exclusions;
}
public String getSessionStatMaxCount() {
return sessionStatMaxCount;
}
public void setSessionStatMaxCount(String sessionStatMaxCount) {
this.sessionStatMaxCount = sessionStatMaxCount;
}
public String getSessionStatEnable() {
return sessionStatEnable;
}
public void setSessionStatEnable(String sessionStatEnable) {
this.sessionStatEnable = sessionStatEnable;
}
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 String getProfileEnable() {
return profileEnable;
}
public void setProfileEnable(String profileEnable) {
this.profileEnable = profileEnable;
}
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.spring.boot.autoconfigure;
import com.alibaba.druid.support.http.StatViewServlet;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
/**
* @author lihengming<89921218@qq.com>
*/
@ConditionalOnProperty(name = "spring.datasource.druid.StatViewServlet.enabled", havingValue = "true", matchIfMissing = true)
public class DruidStatViewServletConfiguration {
@Bean
public ServletRegistrationBean servletRegistrationBean(DruidStatProperties properties) {
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
ServletRegistrationBean registration = new ServletRegistrationBean();
registration.setServlet(new StatViewServlet());
registration.addUrlMappings(config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*");
if (config.getAllow() != null) {
registration.addInitParameter("allow", config.getAllow());
}
if (config.getDeny() != null) {
registration.addInitParameter("deny", config.getDeny());
}
if (config.getLoginUsername() != null) {
registration.addInitParameter("loginUsername", config.getLoginUsername());
}
if (config.getLoginPassword() != null) {
registration.addInitParameter("loginPassword", config.getLoginPassword());
}
if (config.getResetEnable() != null) {
registration.addInitParameter("resetEnable", config.getResetEnable());
}
return registration;
}
}
@@ -0,0 +1,53 @@
/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.spring.boot.autoconfigure;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
/**
* @author lihengming<89921218@qq.com>
*/
@ConditionalOnProperty(name = "spring.datasource.druid.WebStatFilter.enabled", havingValue = "true", matchIfMissing = true)
public class DruidWebStatFilterConfiguration {
@Bean
public FilterRegistrationBean filterRegistrationBean(DruidStatProperties properties) {
DruidStatProperties.StatFilter config = properties.getStatFilter();
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
WebStatFilter filter = new WebStatFilter();
registrationBean.setFilter(filter);
registrationBean.addUrlPatterns(config.getUrlPattern() != null ? config.getUrlPattern() : "/*");
registrationBean.addInitParameter("exclusions", config.getExclusions() != null ? config.getExclusions() : "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
if (config.getSessionStatEnable() != null) {
registrationBean.addInitParameter("sessionStatEnable", config.getSessionStatEnable());
}
if (config.getSessionStatMaxCount() != null) {
registrationBean.addInitParameter("sessionStatMaxCount", config.getSessionStatMaxCount());
}
if (config.getPrincipalSessionName() != null) {
registrationBean.addInitParameter("principalSessionName", config.getPrincipalSessionName());
}
if (config.getPrincipalCookieName() != null) {
registrationBean.addInitParameter("principalCookieName", config.getPrincipalCookieName());
}
if (config.getProfileEnable() != null) {
registrationBean.addInitParameter("profileEnable", config.getProfileEnable());
}
return registrationBean;
}
}
@@ -1,43 +0,0 @@
package org.springframework.boot.autoconfigure.jdbc;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;
import javax.servlet.http.HttpServlet;
import javax.sql.DataSource;
import javax.sql.XADataSource;
/**
* druid auto configuration
*
* @author leijuan
*/
@SuppressWarnings("SpringJavaAutowiringInspection")
@Configuration
@ConditionalOnClass(DruidDataSource.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DruidAutoConfiguration {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid")
@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
public DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().type(DruidDataSource.class).build();
}
@Bean
@ConditionalOnClass(HttpServlet.class)
public ServletRegistrationBean druidStatViewServlet() {
return new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
}
}
@@ -1,10 +0,0 @@
{
"groups": [
{
"name": "spring.datasource.druid",
"type": "com.alibaba.druid.pool.DruidDataSource",
"sourceType": "org.springframework.boot.autoconfigure.jdbc.DruidAutoConfiguration",
"sourceMethod": "dataSource(org.springframework.boot.autoconfigure.jdbc.DataSourceProperties)"
}
]
}
@@ -1 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.springframework.boot.autoconfigure.jdbc.DruidAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
@@ -1 +0,0 @@
provides: druid-spring-boot-starter
@@ -1,36 +0,0 @@
package com.alibaba.boot.druid.demo;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
/**
* druid auto configuration test
*
* @author leijuan
*/
@RunWith(SpringRunner.class)
@ImportAutoConfiguration(DruidDemoApplication.class)
@TestPropertySource("classpath:application.properties")
public class DruidAutoConfigurationTest {
@Autowired
private DataSource dataSource;
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testDatabaseOperations() {
Assert.assertNotNull(dataSource);
}
}
@@ -1,16 +0,0 @@
package com.alibaba.boot.druid.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* druid demo application
*
* @author leijuan
*/
@SpringBootApplication
public class DruidDemoApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(DruidDemoApplication.class, args);
}
}
@@ -0,0 +1,21 @@
package com.alibaba.druid.spring.boot.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author lihengming<89921218@qq.com>
*
* <p>一个简单的使用演示</p>
* <p>1.按需配置application.properties,配置项请参考config-template.properties</p>
* <p>2.run DemoApplication</p>
* <p>3.访问http://127.0.0.1:8080/druid</p>
* <p>4.访问/user/${id}接口,查看SQL、Web、AOP监控效果,如:http://127.0.0.1:8080/user/1</p>
*
*/
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@@ -0,0 +1,8 @@
package com.alibaba.druid.spring.boot.demo.dao;
import com.alibaba.druid.spring.boot.demo.model.User;
import org.springframework.data.repository.CrudRepository;
public interface UserDao extends CrudRepository<User, Long> {}
@@ -0,0 +1,45 @@
package com.alibaba.druid.spring.boot.demo.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public User() {
}
public User(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
@@ -0,0 +1,8 @@
package com.alibaba.druid.spring.boot.demo.service;
import com.alibaba.druid.spring.boot.demo.model.User;
public interface UserService {
User findById(Long id);
}
@@ -0,0 +1,26 @@
package com.alibaba.druid.spring.boot.demo.service;
import com.alibaba.druid.spring.boot.demo.dao.UserDao;
import com.alibaba.druid.spring.boot.demo.model.User;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService,InitializingBean {
@Autowired
private UserDao userDao;
@Override
public User findById(Long id) {
return userDao.findOne(id);
}
@Override
public void afterPropertiesSet() throws Exception {
for (int i = 1; i <= 100; i++) {
userDao.save(new User("TEST-NAME-" + i));
}
}
}
@@ -0,0 +1,20 @@
package com.alibaba.druid.spring.boot.demo.web;
import com.alibaba.druid.spring.boot.demo.model.User;
import com.alibaba.druid.spring.boot.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/user/{id}")
public User list(@PathVariable Long id) {
return userService.findById(id);
}
}
@@ -1,5 +1,13 @@
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/druid
spring.datasource.username=root
spring.datasource.password=123456
# JDBC
spring.datasource.url=jdbc:h2:file:./demo-db
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.driver-class-name=org.h2.Driver
#启用Spring关联监控配置
spring.datasource.druid.aop-patterns=com.alibaba.druid.spring.boot.demo.service.*
#其他配置,参考config-template.properties
# JPA
spring.jpa.show-sql= true
spring.jpa.hibernate.ddl-auto=create-drop
@@ -0,0 +1,42 @@
######Druid数据源配置######
# JDBC配置
spring.datasource.url= #别名为spring.datasource.druid.url
spring.datasource.username= #别名为spring.datasource.druid.username
spring.datasource.password= #别名为spring.datasource.druid.password
spring.datasource.driver-class-name= #别名为spring.datasource.druid.driver-class-name,非必填项可通过url解析
# 连接池配置,下面配置说明请参考Druid Github Wiki,配置_DruidDataSource参考配置
spring.datasource.druid.initialSize=
spring.datasource.druid.minIdle=
spring.datasource.druid.maxActive=
spring.datasource.druid.maxWait=
spring.datasource.druid.timeBetweenEvictionRunsMillis=
spring.datasource.druid.minEvictableIdleTimeMillis=
spring.datasource.druid.validationQuery=
spring.datasource.druid.testWhileIdle=
spring.datasource.druid.testOnBorrow=
spring.datasource.druid.testOnReturn=
spring.datasource.druid.poolPreparedStatements=
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=
spring.datasource.druid.filters= #默认值stat,配置多个英文逗号分隔
######Druid监控配置######
#下面配置说明请参考Druid Github Wiki,配置_配置WebStatFilter
spring.datasource.druid.WebStatFilter.enabled= #是否启用StatFilter默认值true
spring.datasource.druid.WebStatFilter.urlPattern=
spring.datasource.druid.WebStatFilter.exclusions=
spring.datasource.druid.WebStatFilter.sessionStatMaxCount=
spring.datasource.druid.WebStatFilter.sessionStatEnable=
spring.datasource.druid.WebStatFilter.principalSessionName=
spring.datasource.druid.WebStatFilter.principalCookieName=
spring.datasource.druid.WebStatFilter.profileEnable=
#下面配置说明请参考Druid Github Wiki,配置_StatViewServlet配置
spring.datasource.druid.StatViewServlet.enabled= #是否启用StatViewServlet默认值true
spring.datasource.druid.StatViewServlet.urlPattern=
spring.datasource.druid.StatViewServlet.resetEnable=
spring.datasource.druid.StatViewServlet.loginUsername=
spring.datasource.druid.StatViewServlet.loginPassword=
spring.datasource.druid.StatViewServlet.allow=
spring.datasource.druid.StatViewServlet.deny=
#下面配置说明请参考Druid Github Wiki,配置_配置WebStatFilter
spring.datasource.druid.aop-patterns= #Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
#如果spring.datasource.druid.aop-patterns要代理的类没有定义interface请设置spring.aop.proxy-target-class=true