SpringBoot-Druid 框架搭建

初学SpringBoot,在学习过程当中遇到许多问题,因此分享出来;css

在集成Druid数据链接池时,因为SpringBoot默认没有该配置,须要咱们配置,所以花费了好些时间,才整理出来比较简洁的配置方案html

首先新建好SpringBoot项目,java

1:  pom.xml 文件中 引入Jar包:mysql

<!-- MySql数据库 begin-->
		<dependency><!--驱动-->
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.38</version>
		</dependency>
		<dependency><!--链接池-->
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.0.20</version>
		</dependency>
		<!--
			注意: 在配置过程当中 mysql-connector-java 的版本号会 和 druid 冲突,从而 在项目启动时发出:
			com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker -
			Cannot resolve com.mysq.jdbc.Connection.ping method. Will use 'SELECT 1' instead.
			的警告; 因此注意 mysql-connector-java 的版本
		-->
		<!-- MySql数据库 end -->

2: application.yml 文件中 进行数据配置:git

spring:
  #数据源
  datasource:
    #数据库访问配置
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/diary?autoReconnect=true&characterEncoding=utf-8
    username: root
    password: 123456
    #链接池配置
    # 初始化时创建物理链接的个数
    initialSize: 1
    # 最小链接池数量
    minIdle: 1
    # 最大链接池数量
    maxActive: 20
    # 链接时最大等待时间,单位毫秒
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测须要关闭的空闲链接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个链接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    # 用来检测链接是否有效的sql,要求是一个查询语句
    validationQuery: SELECT 1 FROM DUAL
    # 申请链接时执行 validationQuery 检测链接是否有效,作了这个配置会下降性能
    testOnBorrow: false
    # 归还链接时执行 validationQuery 检测链接是否有效,作了这个配置会下降性能
    testOnReturn: false
    # 建议配置为true,不影响性能,而且保证安全性;申请链接的时候检测,
    # 若是空闲时间大于 timeBetweenEvictionRunsMillis,执行 validationQuery 检测链接是否有效
    testWhileIdle: true
    # 是否缓存preparedStatement,也就是 PSCache
    poolPreparedStatements: true
    # 指定每一个链接上 PSCache 的大小
    maxOpenPreparedStatements: 20
    # 配置监控统计拦截的filters,属性类型是字符串,经过别名的方式配置扩展插件,
    # 经常使用的插件有:监控统计用的stat;日志用的log4j;防护sql注入的wall
    filters: stat,wall,log4j
    # 经过 connectProperties 属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.merggSql=ture;druid.stat.slowSqlMillis=5000
    # 合并多个DruidDataSource的监控数据
    useGlobalDataSourceStat: true

3: 编写配置文件:web

package com.gy.demo.config.druid;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;


/**
 * Description : 数据源配置
 * Created by com on  2017/12/6
 *
 * @author geYang
 **/
@Configuration
public class DruidConfig {
	private Logger logger = LoggerFactory.getLogger(DruidConfig.class);
	
	//配置数据源的信息 方法一:
	@Bean(name = "dataSource") @Primary
	@ConfigurationProperties(prefix = "spring.datasource")
	public DataSource dataSource() {
		logger.info("Druid: 开始注入数据源 方法一");
		return DataSourceBuilder.create().type(DruidDataSource.class).build();
	}
	
	//=======    监控统计配置   =======
	
	@Bean
	public ServletRegistrationBean statViewServlet(){
		logger.info("Druid: 配置监控统计的登陆信息");
		ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
		//白名单:
		servletRegistrationBean.addInitParameter("allow","192.168.102.6,127.0.0.1");
		//IP黑名单 (存在共同时,deny优先于allow) : 若是知足deny的即提示:Sorry, you are not permitted to view this page.
		servletRegistrationBean.addInitParameter("deny","192.168.102.6");
		//登陆查看信息的帐号密码.
		servletRegistrationBean.addInitParameter("loginUsername","admin");
		servletRegistrationBean.addInitParameter("loginPassword","admin");
		//是否可以重置数据.
		servletRegistrationBean.addInitParameter("resetEnable","false");
		return servletRegistrationBean;
	}
	
	@Bean
	public FilterRegistrationBean statFilter(){
		logger.info("Druid: 配置监控统计的过滤信息");
		FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
		//添加过滤规则.
		filterRegistrationBean.addUrlPatterns("/*");
		//添加不须要忽略的格式信息.(监控排除的资源)
		filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
		return filterRegistrationBean;
	}
	
	
}

配置到这基本上就可使用了.不过,仍是要注意MySql驱动的版本,避免与Druid冲突,其实尽管冲突,但运行仍是正常的,不会有什么影响,可是像我这样有强迫症的每次启动都要报警告,很不舒服,而后就找问题,找了很久;开始觉得是配置有问题,因此还换了一种配置方式也很好用:spring

(1): 封装Druid数据特性:sql

package com.gy.demo.config.druid;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * Description : Druid 数据源特性实体类
 * Created by com on  2017/12/11
 *
 * @author geYang
 **/
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidEntity {
	
	private String driverClassName;
	private String url;
	private String username;
	private String password;
	private String validationQuery;
	private String filters;
	private String connectionProperties;
	
	private Boolean testOnBorrow;
	private Boolean testOnReturn;
	private Boolean testWhileIdle;
	private Boolean poolPreparedStatements;
	private Boolean useGlobalDataSourceStat;
	
	private Integer initialSize;
	private Integer minIdle;
	private Integer maxActive;
	private Integer maxWait;
	private Integer timeBetweenEvictionRunsMillis;
	private Integer minEvictableIdleTimeMillis;
	private Integer maxOpenPreparedStatements;
	
	public String getDriverClassName () {
		return driverClassName;
	}
	
	public void setDriverClassName (String driverClassName) {
		this.driverClassName = driverClassName;
	}
	
	public String getUrl () {
		return url;
	}
	
	public void setUrl (String url) {
		this.url = url;
	}
	
	public String getUsername () {
		return username;
	}
	
	public void setUsername (String username) {
		this.username = username;
	}
	
	public String getPassword () {
		return password;
	}
	
	public void setPassword (String password) {
		this.password = password;
	}
	
	public String getValidationQuery () {
		return validationQuery;
	}
	
	public void setValidationQuery (String validationQuery) {
		this.validationQuery = validationQuery;
	}
	
	public String getFilters () {
		return filters;
	}
	
	public void setFilters (String filters) {
		this.filters = filters;
	}
	
	public String getConnectionProperties () {
		return connectionProperties;
	}
	
	public void setConnectionProperties (String connectionProperties) {
		this.connectionProperties = connectionProperties;
	}
	
	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 Boolean getPoolPreparedStatements () {
		return poolPreparedStatements;
	}
	
	public void setPoolPreparedStatements (Boolean poolPreparedStatements) {
		this.poolPreparedStatements = poolPreparedStatements;
	}
	
	public Boolean getUseGlobalDataSourceStat () {
		return useGlobalDataSourceStat;
	}
	
	public void setUseGlobalDataSourceStat (Boolean useGlobalDataSourceStat) {
		this.useGlobalDataSourceStat = useGlobalDataSourceStat;
	}
	
	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 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 Integer getMaxOpenPreparedStatements () {
		return maxOpenPreparedStatements;
	}
	
	public void setMaxOpenPreparedStatements (Integer maxOpenPreparedStatements) {
		this.maxOpenPreparedStatements = maxOpenPreparedStatements;
	}
}

(2)进行数据配置:数据库

package com.gy.demo.config.druid;

import com.alibaba.druid.pool.DruidDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * Description : Druid自动配置方法二
 * Created by com on  2017/12/11
 *
 * @author geYang
 **/
@Configuration
@ConditionalOnClass(DruidDataSource.class)
@EnableConfigurationProperties(DruidEntity.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
public class DruidConfigTow {
	private static final Logger logger = LoggerFactory.getLogger(DruidConfigTow.class);
	
	@Resource
	private DruidEntity druidEntity;
	
	@Bean
	public DataSource dataSource() {
		logger.info("Druid: 开始注入数据源 方法二");
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setUrl(druidEntity.getUrl());
		dataSource.setUsername(druidEntity.getUsername());
		dataSource.setPassword(druidEntity.getPassword());
		dataSource.setDriverClassName(druidEntity.getDriverClassName());
		
		if (druidEntity.getValidationQuery()!=null){
			dataSource.setValidationQuery(druidEntity.getValidationQuery());
			logger.info("Druid: 注入 validationQuery");
		}
		
		if (druidEntity.getFilters()!=null){
			try {
				dataSource.setFilters(druidEntity.getFilters());
				logger.info("Druid: 注入 filters 成功");
			} catch (SQLException e) {
				e.printStackTrace();
				logger.info("Druid: 注入 filters 失败");
			}
		}
		
		if (druidEntity.getConnectionProperties()!=null){
			dataSource.setConnectionProperties(druidEntity.getConnectionProperties());
			logger.info("Druid: 注入 connectionProperties");
		}
		
		if (druidEntity.getTestOnBorrow()!=null){
			dataSource.setTestOnBorrow(druidEntity.getTestOnBorrow());
			logger.info("Druid: 注入 testOnBorrow");
		}
		
		if (druidEntity.getTestOnReturn()!=null){
			dataSource.setTestOnReturn(druidEntity.getTestOnReturn());
			logger.info("Druid: 注入 testOnReturn");
		}
		
		if (druidEntity.getTestWhileIdle()!=null){
			dataSource.setTestWhileIdle(druidEntity.getTestWhileIdle());
			logger.info("Druid: 注入 testWhileIdle");
		}
		
		if (druidEntity.getPoolPreparedStatements()!=null){
			dataSource.setPoolPreparedStatements(druidEntity.getPoolPreparedStatements());
			logger.info("Druid: 注入 poolPreparedStatements");
		}
		
		if (druidEntity.getUseGlobalDataSourceStat()!=null){
			dataSource.setUseGlobalDataSourceStat(druidEntity.getUseGlobalDataSourceStat());
			logger.info("Druid: 注入 useGlobalDataSourceStat");
		}
		
		if (druidEntity.getInitialSize()>0){
			dataSource.setInitialSize(druidEntity.getInitialSize());
			logger.info("Druid: 注入 initialSize");
		}
		
		if (druidEntity.getMinIdle()>0){
			dataSource.setMinIdle(druidEntity.getMinIdle());
			logger.info("Druid: 注入 initialSize");
		}
		
		if (druidEntity.getMaxActive()>0){
			dataSource.setMaxActive(druidEntity.getMaxActive());
			logger.info("Druid: 注入 initialSize");
		}
		
		if (druidEntity.getMaxWait()>0){
			dataSource.setMaxWait(druidEntity.getMaxWait());
			logger.info("Druid: 注入 maxWait");
		}
		
		if (druidEntity.getTimeBetweenEvictionRunsMillis()>0){
			dataSource.setTimeBetweenEvictionRunsMillis(druidEntity.getTimeBetweenEvictionRunsMillis());
			logger.info("Druid: 注入 timeBetweenEvictionRunsMillis");
		}
		
		if (druidEntity.getMinEvictableIdleTimeMillis()>0){
			dataSource.setMinEvictableIdleTimeMillis(druidEntity.getMinEvictableIdleTimeMillis());
			logger.info("Druid: 注入 minEvictableIdleTimeMillis");
		}
		
		if (druidEntity.getMaxOpenPreparedStatements()>0){
			dataSource.setMaxOpenPreparedStatements(druidEntity.getMaxOpenPreparedStatements());
			logger.info("Druid: 注入 maxOpenPreparedStatements");
		}
		
		// 初始化
		try {
			dataSource.init();
			logger.info("Druid: dataSource.init() 成功");
		} catch (SQLException e) {
			logger.info("Druid: dataSource.init() 失败");
			e.printStackTrace();
		}
		
		return dataSource;
	}
	
}

(注:  这的方法二,和上面的方法一功能都是相同的,两种方法不会同时使用,若是两个都配置上,则会执行方法一,使用用方法二时,须注释掉方法一(DruidConfig类中的dataSource() 方法;)apache

使用第二种方法配置后,也发生了启动警告;所以去百度了一下,才发现原来是MySQL驱动版本的问题;

将 mysql-connector-java 的jar包版本 由 5.1.6 改成 5.1.38 后就没有出现警告问题;

SpringBoot 与 Druid 的集成配置就基本完成了;

SpringBoot官方文档: https://docs.spring.io/spring-boot/docs/current/reference/html/

项目配置源码: https://gitee.com/ge.yang/SpringBoot

相关文章
相关标签/搜索