詳解Spring Boot下Druid連接池的使用配置分析
引言: 在Spring Boot下默認(rèn)提供了若干種可用的連接池,Druid來(lái)自于阿里系的一個(gè)開(kāi)源連接池,在連接池之外,還提供了非常優(yōu)秀的監(jiān)控功能,這里講解如何與Spring Boot實(shí)現(xiàn)集成。
1. 環(huán)境描述
spring Boot 1.4.0.RELEASE, JDK 1.8
2. Druid介紹
Druid是一個(gè)JDBC組件,它包括三部分:
- DruidDriver 代理Driver,能夠提供基于Filter-Chain模式的插件體系。
- DruidDataSource 高效可管理的數(shù)據(jù)庫(kù)連接池。
- SQLParser
Druid可以做什么?
可以監(jiān)控?cái)?shù)據(jù)庫(kù)訪問(wèn)性能,Druid內(nèi)置提供了一個(gè)功能強(qiáng)大的StatFilter插件,能夠詳細(xì)統(tǒng)計(jì)SQL的執(zhí)行性能,這對(duì)于線上分析數(shù)據(jù)庫(kù)訪問(wèn)性能有幫助。
替換DBCP和C3P0。Druid提供了一個(gè)高效、功能強(qiáng)大、可擴(kuò)展性好的數(shù)據(jù)庫(kù)連接池。
數(shù)據(jù)庫(kù)密碼加密。直接把數(shù)據(jù)庫(kù)密碼寫(xiě)在配置文件中,這是不好的行為,容易導(dǎo)致安全問(wèn)題。DruidDruiver和DruidDataSource都支持PasswordCallback。
SQL執(zhí)行日志,Druid提供了不同的LogFilter,能夠支持Common-Logging、Log4j和JdkLog,你可以按需要選擇相應(yīng)的LogFilter,監(jiān)控你應(yīng)用的數(shù)據(jù)庫(kù)訪問(wèn)情況。
擴(kuò)展JDBC,如果你要對(duì)JDBC層有編程的需求,可以通過(guò)Druid提供的Filter-Chain機(jī)制,很方便編寫(xiě)JDBC層的擴(kuò)展插件。
項(xiàng)目地址: https://github.com/alibaba/druid
3. Spring Boot與Druid的集成
MySQL Driver驅(qū)動(dòng)包:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
Spring Boot的JPA依賴包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
阿里系的Druid依賴包:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.25</version>
</dependency>
Spring Boot中的application.properties配置信息:
# 驅(qū)動(dòng)配置信息 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.url = jdbc:mysql://127.0.0.1:3306/mealsystem?useUnicode=true&characterEncoding=utf-8 spring.datasource.username = root spring.datasource.password = 123456 spring.datasource.driverClassName = com.mysql.jdbc.Driver #連接池的配置信息 spring.datasource.initialSize=5 spring.datasource.minIdle=5 spring.datasource.maxActive=20 spring.datasource.maxWait=60000 spring.datasource.timeBetweenEvictionRunsMillis=60000 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT 1 FROM DUAL spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false spring.datasource.poolPreparedStatements=true spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 spring.datasource.filters=stat,wall,log4j spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
在Spring Boot1.4.0中驅(qū)動(dòng)配置信息沒(méi)有問(wèn)題,但是連接池的配置信息不再支持這里的配置項(xiàng),即無(wú)法通過(guò)配置項(xiàng)直接支持相應(yīng)的連接池;這里列出的這些配置項(xiàng)可以通過(guò)定制化DataSource來(lái)實(shí)現(xiàn)。
目前Spring Boot中默認(rèn)支持的連接池有dbcp,dbcp2, tomcat, hikari三種連接池。
由于Druid暫時(shí)不在Spring Bootz中的直接支持,故需要進(jìn)行配置信息的定制:
@Configuration
public class DruidDBConfig {
private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driverClassName}")
private String driverClassName;
@Value("${spring.datasource.initialSize}")
private int initialSize;
@Value("${spring.datasource.minIdle}")
private int minIdle;
@Value("${spring.datasource.maxActive}")
private int maxActive;
@Value("${spring.datasource.maxWait}")
private int maxWait;
@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis;
@Value("${spring.datasource.validationQuery}")
private String validationQuery;
@Value("${spring.datasource.testWhileIdle}")
private boolean testWhileIdle;
@Value("${spring.datasource.testOnBorrow}")
private boolean testOnBorrow;
@Value("${spring.datasource.testOnReturn}")
private boolean testOnReturn;
@Value("${spring.datasource.poolPreparedStatements}")
private boolean poolPreparedStatements;
@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
private int maxPoolPreparedStatementPerConnectionSize;
@Value("${spring.datasource.filters}")
private String filters;
@Value("{spring.datasource.connectionProperties}")
private String connectionProperties;
@Bean //聲明其為Bean實(shí)例
@Primary //在同樣的DataSource中,首先使用被標(biāo)注的DataSource
public DataSource dataSource(){
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(this.dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
//configuration
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
logger.error("druid configuration initialization filter", e);
}
datasource.setConnectionProperties(connectionProperties);
return datasource;
}
}
DruidDBConfig類被@Configuration標(biāo)注,用作配置信息; DataSource對(duì)象被@Bean聲明,為Spring容器所管理, @Primary表示這里定義的DataSource將覆蓋其他來(lái)源的DataSource。
# 下面為連接池的補(bǔ)充設(shè)置,應(yīng)用到上面所有數(shù)據(jù)源中 # 初始化大小,最小,最大 spring.datasource.initialSize=5 spring.datasource.minIdle=5 spring.datasource.maxActive=20 # 配置獲取連接等待超時(shí)的時(shí)間 spring.datasource.maxWait=60000 # 配置間隔多久才進(jìn)行一次檢測(cè),檢測(cè)需要關(guān)閉的空閑連接,單位是毫秒 spring.datasource.timeBetweenEvictionRunsMillis=60000 # 配置一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT 1 FROM DUAL spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false # 打開(kāi)PSCache,并且指定每個(gè)連接上PSCache的大小 spring.datasource.poolPreparedStatements=true spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 # 配置監(jiān)控統(tǒng)計(jì)攔截的filters,去掉后監(jiān)控界面sql無(wú)法統(tǒng)計(jì),'wall'用于防火墻 spring.datasource.filters=stat,wall,log4j # 通過(guò)connectProperties屬性來(lái)打開(kāi)mergeSql功能;慢SQL記錄 spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合并多個(gè)DruidDataSource的監(jiān)控?cái)?shù)據(jù) #spring.datasource.useGlobalDataSourceStat=true
需要注意的是:spring.datasource.type舊的spring boot版本是不能識(shí)別的。
配置StatView的Servlet:
Filter的實(shí)現(xiàn)類:
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import com.alibaba.druid.support.http.WebStatFilter;
@WebFilter(filterName="druidWebStatFilter",urlPatterns="/*",
initParams={
@WebInitParam(name="exclusions",value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")//忽略資源
}
)
public class DruidStatFilter extends WebStatFilter {
}
StatViewServlet:
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import com.alibaba.druid.support.http.StatViewServlet;
@WebServlet(urlPatterns="/druid/*",
initParams={
@WebInitParam(name="allow",value="127.0.0.1,192.168.163.1"),// IP白名單(沒(méi)有配置或者為空,則允許所有訪問(wèn))
@WebInitParam(name="deny",value="192.168.1.73"),// IP黑名單 (存在共同時(shí),deny優(yōu)先于allow)
@WebInitParam(name="loginUsername",value="admin"),// 用戶名
@WebInitParam(name="loginPassword",value="123456"),// 密碼
@WebInitParam(name="resetEnable",value="false")// 禁用HTML頁(yè)面上的“Reset All”功能
})
public class DruidStatViewServlet extends StatViewServlet {
private static final long serialVersionUID = -2688872071445249539L;
}
這兩個(gè)類相當(dāng)于在web.xml中聲明了一個(gè)servlet, 等價(jià)于如下的配置信息(web.xml):
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
filter的配置信息:
<filter>
<filter-name>DruidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>DruidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
然后相應(yīng)的配置工作就完成了,直接啟動(dòng)即可看到相應(yīng)的應(yīng)用了。
4. 運(yùn)行界面以及介紹
訪問(wèn)地址: http://192.168.163.1:8080/druid/index.html

5. 參考資料
http://blog.csdn.net/xiaoyu411502/article/details/51392237
http://stackoverflow.com/questions/32833641/not-able-to-set-spring-datasource-type
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java圖論弗洛伊德和迪杰斯特拉算法解決最短路徑問(wèn)題
這篇文章主要為大家介紹了java圖論弗洛伊德算法和迪杰斯特拉算法解決最短路徑的問(wèn)題示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11
Java多線程之異步Future機(jī)制的原理和實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Java多線程之異步Future機(jī)制的原理和實(shí)現(xiàn),感興趣的小伙伴們可以參考一下2016-08-08
Java如何實(shí)現(xiàn)多個(gè)線程之間共享數(shù)據(jù)
這篇文章主要介紹了Java如何實(shí)現(xiàn)多個(gè)線程之間共享數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
mybatis-plus動(dòng)態(tài)數(shù)據(jù)源讀寫(xiě)分離方式
在分布式項(xiàng)目開(kāi)發(fā)中,動(dòng)態(tài)數(shù)據(jù)源的配置與使用至關(guān)重要,通過(guò)創(chuàng)建DynamicDatasourceService,實(shí)現(xiàn)數(shù)據(jù)源的動(dòng)態(tài)添加與調(diào)用,有效管理主從庫(kù)操作,減輕數(shù)據(jù)庫(kù)壓力,此外,通過(guò)配置類與@DS注解,實(shí)現(xiàn)了靈活的分庫(kù)查詢功能,為高效處理數(shù)據(jù)提供了強(qiáng)有力的支持2024-10-10
解決定時(shí)任務(wù)@Scheduled沒(méi)有準(zhǔn)時(shí)執(zhí)行的原因及分析

