From 4e8a7296f12a0f14e0eccf29e9b34fa92098ddc7 Mon Sep 17 00:00:00 2001 From: lihengming Date: Wed, 26 Apr 2017 13:23:06 +0800 Subject: [PATCH] add druid-spring-boot-starter support --- druid-spring-boot-starter/README.md | 63 ++++ druid-spring-boot-starter/pom.xml | 113 +++++++ ...ruidDataSourcePropertiesAutoConfigure.java | 76 +++++ .../boot/autoconfigure/DruidProperties.java | 285 ++++++++++++++++++ .../DruidSpringAopConfiguration.java | 39 +++ .../DruidStatFilterConfiguration.java | 41 +++ .../DruidStatViewServletConfiguration.java | 39 +++ .../main/resources/META-INF/spring.factories | 2 + .../boot/autoconfigure/test/Application.java | 21 ++ .../boot/autoconfigure/test/dao/UserDao.java | 7 + .../boot/autoconfigure/test/model/User.java | 45 +++ .../test/service/UserService.java | 7 + .../test/service/UserServiceImpl.java | 25 ++ .../test/web/UserController.java | 19 ++ .../src/test/resources/application.properties | 16 + .../src/test/resources/example.properties | 41 +++ 16 files changed, 839 insertions(+) create mode 100644 druid-spring-boot-starter/README.md create mode 100644 druid-spring-boot-starter/pom.xml create mode 100644 druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourcePropertiesAutoConfigure.java create mode 100644 druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidProperties.java create mode 100644 druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidSpringAopConfiguration.java create mode 100644 druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatFilterConfiguration.java create mode 100644 druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatViewServletConfiguration.java create mode 100644 druid-spring-boot-starter/src/main/resources/META-INF/spring.factories create mode 100644 druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/Application.java create mode 100644 druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/dao/UserDao.java create mode 100644 druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/model/User.java create mode 100644 druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/service/UserService.java create mode 100644 druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/service/UserServiceImpl.java create mode 100644 druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/web/UserController.java create mode 100644 druid-spring-boot-starter/src/test/resources/application.properties create mode 100644 druid-spring-boot-starter/src/test/resources/example.properties diff --git a/druid-spring-boot-starter/README.md b/druid-spring-boot-starter/README.md new file mode 100644 index 0000000000..18b6a826f9 --- /dev/null +++ b/druid-spring-boot-starter/README.md @@ -0,0 +1,63 @@ +# Druid Spring Boot Starter +### 简介 + +使用Spring Boot构建应用已成为Java开发者的首选,Spring 官方提供众多Starter供开发者使用,以便加快应用构建速度。 +Druid作为最好的数据库连接池并未获得Spring 官方的默认支持(目前Spring Boot中默认支持的连接池有dbcp,dbcp2, tomcat, hikari三种连接池)导致Druid连接池配置并不能生效,故开发Druid Spring Boot Starter供使用,使在Spring Boot中使用Druid数据库连接池和监控更为简单。 + +### 如何使用 +(1) ```git clone``` (2) ```mvn:install``` (3) 引入```Maven```依赖 (4) 按需配置```application.properties```,使用默认配置忽略此步 + +注:待上传中央仓库提供\ +### 配置项 +Druid Spring Boot Starter 配置项参数名称是完全遵照Druid的,默认值也是Druid的官方默认值,如果你进行了配置那么默认值将被覆盖。 +``` +# 数据源基础配置,参考Spring Boot文档该部分 +spring.datasource.url= +spring.datasource.username= +spring.datasource.password= +spring.datasource.driver-class-name= +# Druid配置 +spring.datasource.druid.StatViewServlet.enabled= #是否启用StatViewServlet默认值true +spring.datasource.druid.StatFilter.enabled= #是否启用StatFilter默认值true +spring.datasource.druid.filters= #默认值为stat,配置多个请以英文逗号分隔,如stat,wall,log4j +spring.datasource.druid.aop-patterns= #配置AOP切入点来启用Spring监控,配置多个以英文逗号分隔,如x.y.z.dao.*,x.y.z.service.* +#下面配置项说明请参考Druid 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= +#下面配置项说明请参考Druid Wiki,配置_配置WebStatFilter +spring.datasource.druid.StatFilter.urlPattern= +spring.datasource.druid.StatFilter.exclusions= +spring.datasource.druid.StatFilter.sessionStatMaxCount= +spring.datasource.druid.StatFilter.sessionStatEnable= +spring.datasource.druid.StatFilter.principalSessionName= +spring.datasource.druid.StatFilter.principalCookieName= +spring.datasource.druid.StatFilter.profileEnable= +#下面配置项说明请参考Druid Wiki,配置_StatViewServlet配置 +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= + +#如果spring.datasource.druid.aop-patterns要代理的类没有定义interface请设置spring.aop.proxy-target-class=true + +``` +### 演示 +克隆项目,运行```test```包内的```Application.java``` +### 参考 +[Druid Wiki](https://github.com/alibaba/druid/wiki/%E9%A6%96%E9%A1%B5) + +[Spring Boot Reference](http://docs.spring.io/spring-boot/docs/1.5.1.RELEASE/reference/html/) + + diff --git a/druid-spring-boot-starter/pom.xml b/druid-spring-boot-starter/pom.xml new file mode 100644 index 0000000000..27ed72a671 --- /dev/null +++ b/druid-spring-boot-starter/pom.xml @@ -0,0 +1,113 @@ + + + 4.0.0 + + com.alibaba + druid-spring-boot-starter + 0.0.1 + jar + druid-spring-boot-starter + druid-spring-boot-starter + + + UTF-8 + UTF-8 + 1.7 + + + + + + + org.springframework.boot + spring-boot-dependencies + 1.5.1.RELEASE + pom + import + + + + + + + org.springframework.boot + spring-boot-autoconfigure + + + com.alibaba + druid + 1.0.14 + provided + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + test + + + org.springframework.boot + spring-boot-starter-data-jpa + test + + + mysql + mysql-connector-java + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + + + + + + + 李恒名 + https://github.com/lihengming/ + 89921218@qq.com + + + diff --git a/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourcePropertiesAutoConfigure.java b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourcePropertiesAutoConfigure.java new file mode 100644 index 0000000000..a576d4ffc7 --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourcePropertiesAutoConfigure.java @@ -0,0 +1,76 @@ +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.jdbc.DataSourceBuilder; +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 javax.sql.DataSource; +import java.sql.SQLException; + +/** + * @author lihengming<89921218@qq.com> + */ +@Configuration +@ConditionalOnClass(com.alibaba.druid.pool.DruidDataSource.class) +@EnableConfigurationProperties(DruidProperties.class) +@Import({DruidSpringAopConfiguration.class, DruidStatViewServletConfiguration.class, DruidStatFilterConfiguration.class}) +public class DruidDataSourcePropertiesAutoConfigure { + @Bean + @ConfigurationProperties("spring.datasource") + public DataSource dataSource(DruidProperties properties) { + //base datasource config,use spring datasource autoconfig. + DruidDataSource datasource = (DruidDataSource) DataSourceBuilder + .create() + .type(DruidDataSource.class) + .build(); + //druid config. + configDruid(datasource, properties); + return datasource; + } + + private void configDruid(DruidDataSource datasource, DruidProperties properties) { + if (properties.getMaxActive() != null) { + datasource.setMaxActive(properties.getMaxActive()); + } + if (properties.getInitialSize() != null) { + datasource.setInitialSize(properties.getInitialSize()); + } + if (properties.getMaxWait() != null) { + datasource.setMaxWait(properties.getMaxWait()); + } + if (properties.getMinIdle() != null) { + datasource.setMinIdle(properties.getMinIdle()); + } + if (properties.getTimeBetweenEvictionRunsMillis() != null) { + datasource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis()); + } + if (properties.getMinEvictableIdleTimeMillis() != null) { + datasource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis()); + } + if (properties.getTestWhileIdle() != null) { + datasource.setTestWhileIdle(properties.getTestWhileIdle()); + } + if (properties.getTestOnBorrow() != null) { + datasource.setTestOnBorrow(properties.getTestOnBorrow()); + } + if (properties.getTestOnReturn() != null) { + datasource.setTestOnReturn(properties.getTestOnReturn()); + } + if (properties.getPoolPreparedStatements() != null) { + datasource.setPoolPreparedStatements(properties.getPoolPreparedStatements()); + } + if (properties.getMaxPoolPreparedStatementPerConnectionSize() != null) { + datasource.setMaxPoolPreparedStatementPerConnectionSize(properties.getMaxPoolPreparedStatementPerConnectionSize()); + } + try { + datasource.setFilters(properties.getFilters() != null ? properties.getFilters() : "stat"); + } catch (SQLException e) { + throw new IllegalArgumentException("please check your spring.datasource.druid.filters property.", e); + } + } +} diff --git a/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidProperties.java b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidProperties.java new file mode 100644 index 0000000000..2acdc359bb --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidProperties.java @@ -0,0 +1,285 @@ +package com.alibaba.druid.spring.boot.autoconfigure; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author lihengming<89921218@qq.com> + * @see DruidDataSource参考配置 + */ +@ConfigurationProperties("spring.datasource.druid") +public class DruidProperties{ + private Integer initialSize; + private Integer minIdle; + private Integer maxActive; + private Integer maxWait; + private Integer timeBetweenEvictionRunsMillis; + private Integer minEvictableIdleTimeMillis; + private String validationQuery; + private Boolean testOnBorrow; + private Boolean testOnReturn; + private Boolean testWhileIdle; + private String filters; + private Boolean poolPreparedStatements; + private Integer maxPoolPreparedStatementPerConnectionSize; + private String[] aopPatterns; + private StatViewServlet statViewServlet = new StatViewServlet(); + private StatFilter statFilter = new StatFilter(); + + + public Integer getInitialSize() { + return initialSize; + } + + public void setInitialSize(Integer initialSize) { + this.initialSize = initialSize; + } + + public Integer getMinIdle() { + return minIdle; + } + + public void setMinIdle(Integer minIdle) { + this.minIdle = minIdle; + } + + public Integer getMaxActive() { + return maxActive; + } + + public void setMaxActive(Integer maxActive) { + this.maxActive = maxActive; + } + + public Integer getMaxWait() { + return maxWait; + } + + public void setMaxWait(Integer maxWait) { + this.maxWait = maxWait; + } + + public String getValidationQuery() { + return validationQuery; + } + + public void setValidationQuery(String validationQuery) { + this.validationQuery = validationQuery; + } + + public Boolean getTestOnBorrow() { + return testOnBorrow; + } + + public void setTestOnBorrow(Boolean testOnBorrow) { + this.testOnBorrow = testOnBorrow; + } + + public Boolean getTestOnReturn() { + return testOnReturn; + } + + public void setTestOnReturn(Boolean testOnReturn) { + this.testOnReturn = testOnReturn; + } + + public Boolean getTestWhileIdle() { + return testWhileIdle; + } + + public void setTestWhileIdle(Boolean testWhileIdle) { + this.testWhileIdle = testWhileIdle; + } + + public Integer getTimeBetweenEvictionRunsMillis() { + return timeBetweenEvictionRunsMillis; + } + + public void setTimeBetweenEvictionRunsMillis(Integer timeBetweenEvictionRunsMillis) { + this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; + } + + public Integer getMinEvictableIdleTimeMillis() { + return minEvictableIdleTimeMillis; + } + + public void setMinEvictableIdleTimeMillis(Integer minEvictableIdleTimeMillis) { + this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; + } + + public String getFilters() { + return filters; + } + + public void setFilters(String filters) { + this.filters = filters; + } + + public Boolean getPoolPreparedStatements() { + return poolPreparedStatements; + } + + public void setPoolPreparedStatements(Boolean poolPreparedStatements) { + this.poolPreparedStatements = poolPreparedStatements; + } + + public Integer getMaxPoolPreparedStatementPerConnectionSize() { + return maxPoolPreparedStatementPerConnectionSize; + } + + public void setMaxPoolPreparedStatementPerConnectionSize(Integer maxPoolPreparedStatementPerConnectionSize) { + this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize; + } + + 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; + } + + /** + * @see StatViewServlet配置 + */ + 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; + } + } + + /** + * @see 配置WebStatFilter + */ + 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; + } + } +} diff --git a/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidSpringAopConfiguration.java b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidSpringAopConfiguration.java new file mode 100644 index 0000000000..2ac9a9abe2 --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidSpringAopConfiguration.java @@ -0,0 +1,39 @@ +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; + +/** + * The Druid spring aop configuration. + * + * @author lihengming< qq.com> + * @see Druid和Spring关联监控配置 + */ +@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(DruidProperties properties) { + return new RegexpMethodPointcutAdvisor(properties.getAopPatterns(), advice()); + } + + @Bean + public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() { + DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); + advisorAutoProxyCreator.setProxyTargetClass(proxyTargetClass); + return advisorAutoProxyCreator; + } +} diff --git a/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatFilterConfiguration.java b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatFilterConfiguration.java new file mode 100644 index 0000000000..295c4a6f69 --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatFilterConfiguration.java @@ -0,0 +1,41 @@ +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; + +/** + * The Druid stat filter configuration. + * + * @author lihengming< qq.com> + * @see 配置WebStatFilter + */ +@ConditionalOnProperty(name = "spring.datasource.druid.StatFilter.enabled", havingValue = "true", matchIfMissing = true) +public class DruidStatFilterConfiguration { + @Bean + public FilterRegistrationBean filterRegistrationBean(DruidProperties properties) { + DruidProperties.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; + } +} diff --git a/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatViewServletConfiguration.java b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatViewServletConfiguration.java new file mode 100644 index 0000000000..427b5b440a --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatViewServletConfiguration.java @@ -0,0 +1,39 @@ +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; + +/** + * The Druid stat view servlet configuration. + * + * @author lihengming< qq.com> + * @see StatViewServlet配置 + */ +@ConditionalOnProperty(name = "spring.datasource.druid.StatViewServlet.enabled", havingValue = "true", matchIfMissing = true) +public class DruidStatViewServletConfiguration { + @Bean + public ServletRegistrationBean servletRegistrationBean(DruidProperties properties) { + DruidProperties.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; + } +} diff --git a/druid-spring-boot-starter/src/main/resources/META-INF/spring.factories b/druid-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..9686c32427 --- /dev/null +++ b/druid-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourcePropertiesAutoConfigure \ No newline at end of file diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/Application.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/Application.java new file mode 100644 index 0000000000..b37fe32a60 --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/Application.java @@ -0,0 +1,21 @@ +package com.alibaba.druid.spring.boot.autoconfigure.test; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author lihengming<89921218@qq.com> + * + *

druid-spring-boot-starter 测试例子

+ *

1.按需配置application.properties

+ *

2.run Application

+ *

3.访问http://127.0.0.1:8080/druid

+ *

4.访问/user/{id}接口,查看监控效果,如:http://127.0.0.1:8080/user/1

+ * + */ +@SpringBootApplication +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/dao/UserDao.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/dao/UserDao.java new file mode 100644 index 0000000000..9a7d2aa02d --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/dao/UserDao.java @@ -0,0 +1,7 @@ +package com.alibaba.druid.spring.boot.autoconfigure.test.dao; + +import com.alibaba.druid.spring.boot.autoconfigure.test.model.User; +import org.springframework.data.repository.CrudRepository; + +public interface UserDao extends CrudRepository {} + diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/model/User.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/model/User.java new file mode 100644 index 0000000000..90954b2843 --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/model/User.java @@ -0,0 +1,45 @@ +package com.alibaba.druid.spring.boot.autoconfigure.test.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 + '\'' + + '}'; + } +} diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/service/UserService.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/service/UserService.java new file mode 100644 index 0000000000..2bbfb2f671 --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/service/UserService.java @@ -0,0 +1,7 @@ +package com.alibaba.druid.spring.boot.autoconfigure.test.service; + +import com.alibaba.druid.spring.boot.autoconfigure.test.model.User; + +public interface UserService { + User findById(Long id); +} diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/service/UserServiceImpl.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/service/UserServiceImpl.java new file mode 100644 index 0000000000..2e5828b87c --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/service/UserServiceImpl.java @@ -0,0 +1,25 @@ +package com.alibaba.druid.spring.boot.autoconfigure.test.service; + +import com.alibaba.druid.spring.boot.autoconfigure.test.dao.UserDao; +import com.alibaba.druid.spring.boot.autoconfigure.test.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)); + } + } +} diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/web/UserController.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/web/UserController.java new file mode 100644 index 0000000000..7ec6105d11 --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/autoconfigure/test/web/UserController.java @@ -0,0 +1,19 @@ +package com.alibaba.druid.spring.boot.autoconfigure.test.web; + +import com.alibaba.druid.spring.boot.autoconfigure.test.service.UserService; +import com.alibaba.druid.spring.boot.autoconfigure.test.model.User; +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); + } +} diff --git a/druid-spring-boot-starter/src/test/resources/application.properties b/druid-spring-boot-starter/src/test/resources/application.properties new file mode 100644 index 0000000000..542bfb8b7b --- /dev/null +++ b/druid-spring-boot-starter/src/test/resources/application.properties @@ -0,0 +1,16 @@ +# \u6570\u636E\u6E90\u57FA\u7840\u914D\u7F6E\uFF0C\u8BF7\u4FEE\u6539\u4E3A\u4F60\u7684JDBC\u914D\u7F6E +spring.datasource.url=jdbc:mysql://localhost:3306/your-db +spring.datasource.username=your-username +spring.datasource.password=your-password +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +# Druid\u914D\u7F6E\uFF0C\u81EA\u884C\u589E\u5220\u914D\u7F6E +#spring.datasource.druid.maxActive=20 +spring.datasource.druid.filters=stat,wall,log4j +spring.datasource.druid.aop-patterns=com.alibaba.druid.spring.boot.autoconfigure.test.service.* +#spring.datasource.druid.StatViewServlet.loginUsername=admin +#spring.datasource.druid.StatViewServlet.loginPassword=123456 +# JPA +spring.jpa.show-sql= true +spring.jpa.hibernate.ddl-auto=create-drop +# \u5982\u679Cspring.datasource.druid.aop-patterns\u8981\u4EE3\u7406\u7684\u7C7B\u6CA1\u6709\u5B9A\u4E49interface\u8BF7\u8BBE\u7F6Espring.aop.proxy-target-class=true +# spring.aop.proxy-target-class=true diff --git a/druid-spring-boot-starter/src/test/resources/example.properties b/druid-spring-boot-starter/src/test/resources/example.properties new file mode 100644 index 0000000000..65f00be9f0 --- /dev/null +++ b/druid-spring-boot-starter/src/test/resources/example.properties @@ -0,0 +1,41 @@ +# \u6570\u636E\u6E90\u57FA\u7840\u914D\u7F6E\uFF0C\u53C2\u8003Spring Boot\u6587\u6863\u8BE5\u90E8\u5206 +spring.datasource.url= +spring.datasource.username= +spring.datasource.password= +spring.datasource.driver-class-name= +# Druid\u914D\u7F6E +spring.datasource.druid.StatViewServlet.enabled= #\u662F\u5426\u542F\u7528StatViewServlet\u9ED8\u8BA4\u503Ctrue +spring.datasource.druid.StatFilter.enabled= #\u662F\u5426\u542F\u7528StatFilter\u9ED8\u8BA4\u503Ctrue +spring.datasource.druid.filters= #\u9ED8\u8BA4\u503Cstat\uFF0C\u914D\u7F6E\u591A\u4E2A\u82F1\u6587\u9017\u53F7\u5206\u9694 +spring.datasource.druid.aop-patterns= #Spring\u76D1\u63A7AOP\u5207\u5165\u70B9\uFF0C\u5982x.y.z.service.*,\u914D\u7F6E\u591A\u4E2A\u82F1\u6587\u9017\u53F7\u5206\u9694 +#\u4E0B\u9762\u914D\u7F6E\u8BF4\u660E\u8BF7\u53C2\u8003Druid Github Wiki\uFF0C\u914D\u7F6E_DruidDataSource\u53C2\u8003\u914D\u7F6E +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= +#\u4E0B\u9762\u914D\u7F6E\u8BF4\u660E\u8BF7\u53C2\u8003Druid Github Wiki\uFF0C\u914D\u7F6E_\u914D\u7F6EWebStatFilter +spring.datasource.druid.StatFilter.urlPattern= +spring.datasource.druid.StatFilter.exclusions= +spring.datasource.druid.StatFilter.sessionStatMaxCount= +spring.datasource.druid.StatFilter.sessionStatEnable= +spring.datasource.druid.StatFilter.principalSessionName= +spring.datasource.druid.StatFilter.principalCookieName= +spring.datasource.druid.StatFilter.profileEnable= +#\u4E0B\u9762\u914D\u7F6E\u8BF4\u660E\u8BF7\u53C2\u8003Druid Github Wiki\uFF0C\u914D\u7F6E_StatViewServlet\u914D\u7F6E +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= + + +#\u5982\u679Cspring.datasource.druid.aop-patterns\u8981\u4EE3\u7406\u7684\u7C7B\u6CA1\u6709\u5B9A\u4E49interface\u8BF7\u8BBE\u7F6Espring.aop.proxy-target-class=true