diff --git a/druid-spring-boot-starter/.gitignore b/druid-spring-boot-starter/.gitignore new file mode 100644 index 0000000000..f3340860d1 --- /dev/null +++ b/druid-spring-boot-starter/.gitignore @@ -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/ \ No newline at end of file diff --git a/druid-spring-boot-starter/README.md b/druid-spring-boot-starter/README.md index 73fdc917ce..d511ab5578 100644 --- a/druid-spring-boot-starter/README.md +++ b/druid-spring-boot-starter/README.md @@ -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 - - com.alibaba.boot - druid-spring-boot-starter - 1.0.0-SNAPSHOT - + + com.alibaba + druid-spring-boot-starter + 1.0.29-SNAPSHOT + ``` -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 \ No newline at end of file +[Spring Boot Reference](http://docs.spring.io/spring-boot/docs/1.5.1.RELEASE/reference/html/) \ No newline at end of file diff --git a/druid-spring-boot-starter/pom.xml b/druid-spring-boot-starter/pom.xml index 26c469fdb1..eddfb3a47e 100644 --- a/druid-spring-boot-starter/pom.xml +++ b/druid-spring-boot-starter/pom.xml @@ -2,77 +2,25 @@ 4.0.0 - com.alibaba.boot + com.alibaba druid-spring-boot-starter - 5.1.26-SNAPSHOT + 1.0.29-SNAPSHOT jar - tddl-spring-boot-starter - http://gitlab.alibaba-inc.com/sping-boot/tddl-spring-boot-starter + druid-spring-boot-starter - 1.4.5.RELEASE 1.0.29 + 1.5.3.RELEASE - leijuan - 雷卷 - jacky.chenlb@alibaba-inc.com - https://work.alibaba-inc.com/work/u/7883 - - 开发人员 - + 李恒名 + https://github.com/lihengming/ + 89921218@qq.com - - scm:git:git@gitlab.alibaba-inc.com:spring-boot-incubator/druid-spring-boot-starter.git - scm:git:git@gitlab.alibaba-inc.com:spring-boot-incubator/druid-spring-boot-starter.git - - http://gitlab.alibaba-inc.com/spring-boot-incubator/druid-spring-boot-starter - - - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-jdbc - - - com.alibaba - druid - ${druid.version} - - - mysql - mysql-connector-java - - - org.springframework.boot - spring-boot-configuration-processor - true - - - junit - junit - test - - - org.springframework.boot - spring-boot-starter-test - test - - - @@ -87,4 +35,121 @@ + + + + com.alibaba + druid + ${druid.version} + + + org.springframework.boot + spring-boot-autoconfigure + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + javax.servlet + javax.servlet-api + provided + + + + org.springframework.boot + spring-boot-starter-web + test + + + + org.springframework.boot + spring-boot-starter-data-jpa + test + + + + com.h2database + h2 + test + + + + + scm:git:git@gitlab.alibaba-inc.com:spring-boot-incubator/druid-spring-boot-starter.git + scm:git:git@gitlab.alibaba-inc.com:spring-boot-incubator/druid-spring-boot-starter.git + + http://gitlab.alibaba-inc.com/spring-boot-incubator/druid-spring-boot-starter + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.1 + + 1.7 + 1.7 + + + + 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 + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + + + releases + https://oss.sonatype.org/service/local/staging/deploy/maven2 + + + snapshots + https://oss.sonatype.org/content/repositories/snapshots + + https://oss.sonatype.org/content/groups/public + diff --git a/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceAutoConfigure.java b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceAutoConfigure.java new file mode 100644 index 0000000000..21bf9082dd --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceAutoConfigure.java @@ -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; + } +} diff --git a/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceBuilder.java b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceBuilder.java new file mode 100644 index 0000000000..fd1efb0408 --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceBuilder.java @@ -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 properties = new HashMap(); + + 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); + } + } +} 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..4f3849e641 --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidSpringAopConfiguration.java @@ -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; + } +} diff --git a/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatProperties.java b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatProperties.java new file mode 100644 index 0000000000..520a1ea22d --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatProperties.java @@ -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; + } + } +} 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..89ad8e59d8 --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidStatViewServletConfiguration.java @@ -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; + } +} diff --git a/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidWebStatFilterConfiguration.java b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidWebStatFilterConfiguration.java new file mode 100644 index 0000000000..3ca1b85763 --- /dev/null +++ b/druid-spring-boot-starter/src/main/java/com/alibaba/druid/spring/boot/autoconfigure/DruidWebStatFilterConfiguration.java @@ -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; + } +} diff --git a/druid-spring-boot-starter/src/main/java/org/springframework/boot/autoconfigure/jdbc/DruidAutoConfiguration.java b/druid-spring-boot-starter/src/main/java/org/springframework/boot/autoconfigure/jdbc/DruidAutoConfiguration.java deleted file mode 100644 index 8853530a4f..0000000000 --- a/druid-spring-boot-starter/src/main/java/org/springframework/boot/autoconfigure/jdbc/DruidAutoConfiguration.java +++ /dev/null @@ -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/*"); - } - -} diff --git a/druid-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/druid-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index f3579b2411..0000000000 --- a/druid-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -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)" - } - ] -} \ No newline at end of file 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 index 722d06388c..a2c21bc315 100644 --- a/druid-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/druid-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -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 \ No newline at end of file diff --git a/druid-spring-boot-starter/src/main/resources/META-INF/spring.provides b/druid-spring-boot-starter/src/main/resources/META-INF/spring.provides deleted file mode 100644 index aaa8cab665..0000000000 --- a/druid-spring-boot-starter/src/main/resources/META-INF/spring.provides +++ /dev/null @@ -1 +0,0 @@ -provides: druid-spring-boot-starter \ No newline at end of file diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/boot/druid/demo/DruidAutoConfigurationTest.java b/druid-spring-boot-starter/src/test/java/com/alibaba/boot/druid/demo/DruidAutoConfigurationTest.java deleted file mode 100644 index 397b4d27a3..0000000000 --- a/druid-spring-boot-starter/src/test/java/com/alibaba/boot/druid/demo/DruidAutoConfigurationTest.java +++ /dev/null @@ -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); - } - -} diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/boot/druid/demo/DruidDemoApplication.java b/druid-spring-boot-starter/src/test/java/com/alibaba/boot/druid/demo/DruidDemoApplication.java deleted file mode 100644 index e1a12f3ee4..0000000000 --- a/druid-spring-boot-starter/src/test/java/com/alibaba/boot/druid/demo/DruidDemoApplication.java +++ /dev/null @@ -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); - } -} diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/DemoApplication.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/DemoApplication.java new file mode 100644 index 0000000000..a8deab6a35 --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/DemoApplication.java @@ -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> + * + *

一个简单的使用演示

+ *

1.按需配置application.properties,配置项请参考config-template.properties

+ *

2.run DemoApplication

+ *

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

+ *

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

+ * + */ +@SpringBootApplication +public class DemoApplication { + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } +} diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/dao/UserDao.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/dao/UserDao.java new file mode 100644 index 0000000000..6037cdbfae --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/dao/UserDao.java @@ -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 {} + diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/model/User.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/model/User.java new file mode 100644 index 0000000000..32eadfa2be --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/model/User.java @@ -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 + '\'' + + '}'; + } +} diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/service/UserService.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/service/UserService.java new file mode 100644 index 0000000000..b9e5075a9c --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/service/UserService.java @@ -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); +} diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/service/UserServiceImpl.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/service/UserServiceImpl.java new file mode 100644 index 0000000000..d6cac398cf --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/service/UserServiceImpl.java @@ -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)); + } + } +} diff --git a/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/web/UserController.java b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/web/UserController.java new file mode 100644 index 0000000000..7ad2b5d68b --- /dev/null +++ b/druid-spring-boot-starter/src/test/java/com/alibaba/druid/spring/boot/demo/web/UserController.java @@ -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); + } +} diff --git a/druid-spring-boot-starter/src/test/resources/application.properties b/druid-spring-boot-starter/src/test/resources/application.properties index 8d0970e716..0ca9a476fb 100644 --- a/druid-spring-boot-starter/src/test/resources/application.properties +++ b/druid-spring-boot-starter/src/test/resources/application.properties @@ -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 - \ No newline at end of file +# 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 + diff --git a/druid-spring-boot-starter/src/test/resources/config-template.properties b/druid-spring-boot-starter/src/test/resources/config-template.properties new file mode 100644 index 0000000000..3c4b2d3af7 --- /dev/null +++ b/druid-spring-boot-starter/src/test/resources/config-template.properties @@ -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