1. 重构 druid-spring-boot-starter 并入主项目。

2. 提供DruidDataSourceBuilder支持Spring Boot下Druid多数据源配置。
This commit is contained in:
lihengming
2017-04-27 16:12:53 +08:00
parent 261e8956cf
commit 893b7e4fe7
16 changed files with 229 additions and 159 deletions
@@ -1,2 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourcePropertiesAutoConfigure
@@ -1,7 +0,0 @@
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<User, Long> {}
@@ -1,7 +0,0 @@
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);
}
@@ -0,0 +1,60 @@
/*
* 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.support.spring.boot.autoconfigure;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
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;
/**
* The Druid data source auto configure.
*
* @author lihengming<89921218@qq.com>
*/
@Configuration
@ConditionalOnClass(com.alibaba.druid.pool.DruidDataSource.class)
@EnableConfigurationProperties(DruidStatProperties.class)
@Import({DruidSpringAopConfiguration.class, DruidStatViewServletConfiguration.class, DruidStatFilterConfiguration.class})
public class DruidDataSourceAutoConfigure {
@Bean
@ConfigurationProperties("spring.datasource.druid")
public DataSource dataSource(Environment env) {
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
//if not found prefix spring.datasource.druid property,spring.datasource prefix property 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"));
}
return dataSource;
}
}
@@ -0,0 +1,64 @@
/*
* 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.support.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;
/**
* The Druid data source builder.
*
* @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 RelaxedDataBinder by reflection config druid .
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);
}
}
}
@@ -1,4 +1,19 @@
package com.alibaba.druid.spring.boot.autoconfigure;
/*
* 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.support.spring.boot.autoconfigure;
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import org.aopalliance.aop.Advice;
@@ -12,7 +27,7 @@ import org.springframework.context.annotation.Bean;
/**
* The Druid spring aop configuration.
*
* @author lihengming< qq.com>
* @author lihengming<89921218@qq.com>
* @see <a href="https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_Druid%E5%92%8CSpring%E5%85%B3%E8%81%94%E7%9B%91%E6%8E%A7%E9%85%8D%E7%BD%AE">Druid和Spring关联监控配置</a>
*/
@ConditionalOnProperty("spring.datasource.druid.aop-patterns")
@@ -26,7 +41,7 @@ public class DruidSpringAopConfiguration {
}
@Bean
public Advisor advisor(DruidProperties properties) {
public Advisor advisor(DruidStatProperties properties) {
return new RegexpMethodPointcutAdvisor(properties.getAopPatterns(), advice());
}
@@ -1,4 +1,19 @@
package com.alibaba.druid.spring.boot.autoconfigure;
/*
* 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.support.spring.boot.autoconfigure;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -8,14 +23,14 @@ import org.springframework.context.annotation.Bean;
/**
* The Druid stat filter configuration.
*
* @author lihengming< qq.com>
* @author lihengming<89921218@qq.com>
* @see <a href="https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_%E9%85%8D%E7%BD%AEWebStatFilter">配置WebStatFilter</a>
*/
@ConditionalOnProperty(name = "spring.datasource.druid.StatFilter.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnProperty(name = "spring.datasource.druid.stat.StatFilter.enabled", havingValue = "true", matchIfMissing = true)
public class DruidStatFilterConfiguration {
@Bean
public FilterRegistrationBean filterRegistrationBean(DruidProperties properties) {
DruidProperties.StatFilter config = properties.getStatFilter();
public FilterRegistrationBean filterRegistrationBean(DruidStatProperties properties) {
DruidStatProperties.StatFilter config = properties.getStatFilter();
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
WebStatFilter filter = new WebStatFilter();
registrationBean.setFilter(filter);
@@ -1,135 +1,34 @@
package com.alibaba.druid.spring.boot.autoconfigure;
/*
* 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.support.spring.boot.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* The type Druid stat properties.
*
* @author lihengming<89921218@qq.com>
* @see <a href="https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_DruidDataSource%E5%8F%82%E8%80%83%E9%85%8D%E7%BD%AE">DruidDataSource参考配置</a>
*/
@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;
public class DruidStatProperties {
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;
}
@@ -157,7 +56,7 @@ public class DruidProperties{
/**
* @see <a href="https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE">StatViewServlet配置</a>
*/
public static class StatViewServlet{
public static class StatViewServlet {
private String urlPattern;
private String allow;
private String deny;
@@ -217,7 +116,7 @@ public class DruidProperties{
/**
* @see <a href="https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_%E9%85%8D%E7%BD%AEWebStatFilter">配置WebStatFilter</a>
*/
public static class StatFilter{
public static class StatFilter {
private String urlPattern;
private String exclusions;
private String sessionStatMaxCount;
@@ -1,4 +1,19 @@
package com.alibaba.druid.spring.boot.autoconfigure;
/*
* 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.support.spring.boot.autoconfigure;
import com.alibaba.druid.support.http.StatViewServlet;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -8,14 +23,14 @@ import org.springframework.context.annotation.Bean;
/**
* The Druid stat view servlet configuration.
*
* @author lihengming< qq.com>
* @author lihengming<89921218@qq.com>
* @see <a href="https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE">StatViewServlet配置</a>
*/
@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();
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/*");
@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.druid.support.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
@@ -1,4 +1,4 @@
package com.alibaba.druid.spring.boot.autoconfigure.test;
package com.alibaba.druid.spring.boot.autoconfigure;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -7,7 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* @author lihengming<89921218@qq.com>
*
* <p>druid-spring-boot-starter 测试例子</p>
* <p>1.按需配置application.properties</p>
* <p>1.按需配置application.properties,配置项请参考</p>
* <p>2.run Application</p>
* <p>3.访问http://127.0.0.1:8080/druid</p>
* <p>4.访问/user/{id}接口,查看监控效果,如:http://127.0.0.1:8080/user/1</p>
@@ -0,0 +1,8 @@
package com.alibaba.druid.spring.boot.autoconfigure.dao;
import com.alibaba.druid.spring.boot.autoconfigure.model.User;
import org.springframework.data.repository.CrudRepository;
public interface UserDao extends CrudRepository<User, Long> {}
@@ -1,4 +1,4 @@
package com.alibaba.druid.spring.boot.autoconfigure.test.model;
package com.alibaba.druid.spring.boot.autoconfigure.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -0,0 +1,8 @@
package com.alibaba.druid.spring.boot.autoconfigure.service;
import com.alibaba.druid.spring.boot.autoconfigure.model.User;
public interface UserService {
User findById(Long id);
}
@@ -1,7 +1,7 @@
package com.alibaba.druid.spring.boot.autoconfigure.test.service;
package com.alibaba.druid.spring.boot.autoconfigure.service;
import com.alibaba.druid.spring.boot.autoconfigure.test.dao.UserDao;
import com.alibaba.druid.spring.boot.autoconfigure.test.model.User;
import com.alibaba.druid.spring.boot.autoconfigure.dao.UserDao;
import com.alibaba.druid.spring.boot.autoconfigure.model.User;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -1,7 +1,7 @@
package com.alibaba.druid.spring.boot.autoconfigure.test.web;
package com.alibaba.druid.spring.boot.autoconfigure.web;
import com.alibaba.druid.spring.boot.autoconfigure.test.service.UserService;
import com.alibaba.druid.spring.boot.autoconfigure.test.model.User;
import com.alibaba.druid.spring.boot.autoconfigure.model.User;
import com.alibaba.druid.spring.boot.autoconfigure.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;