Spring Boot集成Druid數(shù)據(jù)源

Spring Boot官方推薦的數(shù)據(jù)庫連接池是HikariCP,從一些第三方的評測結(jié)果看挠铲,HikariCP的性能比Druid要好寂诱,但是Druid自帶各種監(jiān)控工具,背后又有阿里一直在為它背書瓢棒,還是迎得了很多人的歡迎带迟,本文就講述Spring Boot如何集成Druid數(shù)據(jù)源。
由于Spring Boot的1.3.X和1.4.X版本對druid的配置方法略有不同仓犬,下面分開來描述搀继。

Spring Boot 1.3.X 配置

引入Druid依賴

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.23</version>
        </dependency>

application.properties中新增數(shù)據(jù)庫連接池配置

#druid datasouce database settings begin
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring_boot?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456

# 下面為連接池的補(bǔ)充設(shè)置,應(yīng)用到上面所有數(shù)據(jù)源中
# 初始化大小财边,最小点骑,最大
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
# 配置獲取連接等待超時的時間
spring.datasource.maxWait=60000
# 配置間隔多久才進(jìn)行一次檢測谍夭,檢測需要關(guān)閉的空閑連接紧索,單位是毫秒
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
# 打開PSCache,并且指定每個連接上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置監(jiān)控統(tǒng)計攔截的filters媳危,去掉后監(jiān)控界面sql無法統(tǒng)計冈敛,'wall'用于防火墻
spring.datasource.filters=stat,wall,log4j
# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多個DruidDataSource的監(jiān)控數(shù)據(jù)
spring.datasource.useGlobalDataSourceStat=true
#druid datasouce database settings end

定義Filter滋觉,忽略靜態(tài)資源的攔截

package com.bluecoffee.filter;

import com.alibaba.druid.support.http.WebStatFilter;

import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

/**
 * Created by qianlong on 16/12/21.
 */
@WebFilter(filterName="druidStatFilter",urlPatterns="/*",
        initParams={
                @WebInitParam(name="exclusions",value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")// 忽略資源
        })
public class DruidStatFilter extends WebStatFilter {

}

定義Servlet齐邦,用于Druid控制臺的查看

package com.bluecoffee.servlet;

import com.alibaba.druid.support.http.StatViewServlet;

import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

/**
 * Created by qianlong on 16/8/25.
 */
@SuppressWarnings("serial")
@WebServlet(urlPatterns = "/druid/*",
        initParams={
                @WebInitParam(name="allow",value="192.168.16.110,127.0.0.1"),// IP白名單 (沒有配置或者為空措拇,則允許所有訪問)
                @WebInitParam(name="deny",value="192.168.16.111"),// IP黑名單 (存在共同時慎宾,deny優(yōu)先于allow)
                @WebInitParam(name="loginUsername",value="admin"),// 用戶名
                @WebInitParam(name="loginPassword",value="123456"),// 密碼
                @WebInitParam(name="resetEnable",value="false")// 禁用HTML頁面上的“Reset All”功能
        })
public class DruidStatViewServlet extends StatViewServlet {

}

主執(zhí)行類上注意要加上@ServletComponentScan注解,否則Servlet無法生效

@SpringBootApplication
@ServletComponentScan
@Configuration
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) throws Exception {
        System.out.println("------------Application is start---------------");
        SpringApplication.run(Application.class, args);
    }
}

接下來就可以打開http://localhost:8080/druid/index.html看到效果了券犁,如下圖所示

Druid控制臺

Spring Boot 1.4.X配置

我一開始是在1.3.3.RELEASE版本上集成Druid粘衬,遷移到Spring Boot1.4.2版本時發(fā)現(xiàn)SQL控制臺無論如何都無法監(jiān)控到SQL操作咳促,不得已使用@Bean裝配方式來配置Druid數(shù)據(jù)源,終于發(fā)現(xiàn)可以正常工作了褂删。沒看過源碼冲茸,但猜想可能是由于Spring Boot升級版本的時候缅帘,與Druid有沖突难衰,下面講述@Bean裝配方式實現(xiàn)Druid數(shù)據(jù)源配置。

新增Druid數(shù)據(jù)源配置文件

刪除原有application.properties中druid的相關(guān)配置铃诬,新增druid-config.properties配置文件

#druid datasouce database settings begin
spring.druid.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.druid.datasource.driverClassName=com.mysql.jdbc.Driver
spring.druid.datasource.url=jdbc:mysql://localhost:3306/spring_boot?characterEncoding=utf-8
spring.druid.datasource.username=root
spring.druid.datasource.password=123456

# 下面為連接池的補(bǔ)充設(shè)置苍凛,應(yīng)用到上面所有數(shù)據(jù)源中
# 初始化大小,最小宣肚,最大
spring.druid.datasource.initialSize=5
spring.druid.datasource.minIdle=5
spring.druid.datasource.maxActive=20
# 配置獲取連接等待超時的時間
spring.druid.datasource.maxWait=60000
# 配置間隔多久才進(jìn)行一次檢測悠栓,檢測需要關(guān)閉的空閑連接,單位是毫秒
spring.druid.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一個連接在池中最小生存的時間笙瑟,單位是毫秒
spring.druid.datasource.minEvictableIdleTimeMillis=300000
spring.druid.datasource.validationQuery=SELECT 1 FROM DUAL
spring.druid.datasource.testWhileIdle=true
spring.druid.datasource.testOnBorrow=false
spring.druid.datasource.testOnReturn=false
# 打開PSCache癞志,并且指定每個連接上PSCache的大小
spring.druid.datasource.poolPreparedStatements=true
spring.druid.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置監(jiān)控統(tǒng)計攔截的filters,去掉后監(jiān)控界面sql無法統(tǒng)計错洁,'wall'用于防火墻
spring.druid.datasource.filters=stat,wall,log4j,config
# 通過connectProperties屬性來打開mergeSql功能戒突;慢SQL記錄
spring.druid.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多個DruidDataSource的監(jiān)控數(shù)據(jù)
spring.druid.datasource.useGlobalDataSourceStat=true
#druid datasouce database settings end

新增屬性讀取類DruidSettings.java

package com.bluecoffee.configuration;

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

/**
 * Created by qianlong on 2016/12/21.
 */
@ConfigurationProperties(prefix = "spring.druid.datasource",locations = "classpath:druid-config.properties")
public class DruidSettings {

    private String type;
    private String driverClassName;
    private String url;
    private String username;
    private String password;

    private Integer initialSize;
    private Integer minIdle;
    private Integer maxActive;
    private Long maxWait;
    private Long timeBetweenEvictionRunsMillis;
    private Long minEvictableIdleTimeMillis;
    private String validationQuery;
    private boolean testWhileIdle;
    private boolean testOnBorrow;
    private boolean testOnReturn;
    private boolean poolPreparedStatements;
    private Integer maxPoolPreparedStatementPerConnectionSize;
    private String filters;
    private String connectionProperties;
    private boolean useGlobalDataSourceStat;

    //省略getter/setter方法

}

用Bean方式讀取配置并實例化數(shù)據(jù)源

package com.bluecoffee.configuration;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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 java.util.Properties;

/**
 * Created by qianlong on 2016/12/21.
 */
@Configuration
@EnableConfigurationProperties(DruidSettings.class)
public class DruidDataSourceConfig {

    @Autowired
    private DruidSettings druidSettings;

    @Bean
    @ConfigurationProperties("spring.druid.datasource")
    public DruidDataSource dataSource(
            DataSourceProperties properties) throws Exception{
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(druidSettings.getDriverClassName());
        dataSource.setUrl(druidSettings.getUrl());
        dataSource.setUsername(druidSettings.getUsername());
        dataSource.setPassword(druidSettings.getPassword());
        dataSource.setInitialSize(druidSettings.getInitialSize());
        dataSource.setMinIdle(druidSettings.getMinIdle());
        dataSource.setMaxActive(druidSettings.getMaxActive());
        dataSource.setMaxWait(druidSettings.getMaxWait());
        dataSource.setTimeBetweenEvictionRunsMillis(druidSettings.getTimeBetweenEvictionRunsMillis());
        dataSource.setMinEvictableIdleTimeMillis(druidSettings.getMinEvictableIdleTimeMillis());
        String validationQuery = druidSettings.getValidationQuery();
        if (validationQuery != null && !"".equals(validationQuery)) {
            dataSource.setValidationQuery(validationQuery);
        }
        dataSource.setTestWhileIdle(druidSettings.isTestWhileIdle());
        dataSource.setTestOnBorrow(druidSettings.isTestOnBorrow());
        dataSource.setTestOnReturn(druidSettings.isTestOnReturn());
        if(druidSettings.isPoolPreparedStatements()){
            dataSource.setMaxPoolPreparedStatementPerConnectionSize(druidSettings.getMaxPoolPreparedStatementPerConnectionSize());
        }
        dataSource.setFilters(druidSettings.getFilters());//這是最關(guān)鍵的,否則SQL監(jiān)控?zé)o法生效
        String connectionPropertiesStr = druidSettings.getConnectionProperties();
        if(connectionPropertiesStr != null && !"".equals(connectionPropertiesStr)){
            Properties connectProperties = new Properties();
            String[] propertiesList = connectionPropertiesStr.split(";");
            for(String propertiesTmp:propertiesList){
                String[] obj = propertiesTmp.split("=");
                String key = obj[0];
                String value = obj[1];
                connectProperties.put(key,value);
            }
            dataSource.setConnectProperties(connectProperties);
        }
        dataSource.setUseGlobalDataSourceStat(druidSettings.isUseGlobalDataSourceStat());

        return dataSource;
    }
}

此時再執(zhí)行主執(zhí)行類即可正常運行Druid控制臺

完整代碼戳這里: Chapter 4-1-3 - Spring Boot集成Druid數(shù)據(jù)源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膝舅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子仍稀,更是在濱河造成了極大的恐慌,老刑警劉巖遥巴,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拾弃,居然都是意外死亡摆霉,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門搭盾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來婉支,“玉大人,你說我怎么就攤上這事蝌以『沃” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵碍彭,是天一觀的道長悼潭。 經(jīng)常有香客問我舞箍,道長,這世上最難降的妖魔是什么疏橄? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任捎迫,我火速辦了婚禮,結(jié)果婚禮上窄绒,老公的妹妹穿的比我還像新娘。我一直安慰自己彰导,他們只是感情好敲茄,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布堰燎。 她就那樣靜靜地躺著笋轨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪爵政。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天何什,我揣著相機(jī)與錄音等龙,去河邊找鬼。 笑死罐栈,一個胖子當(dāng)著我的面吹牛泥畅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播柑贞,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼聂抢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了有决?” 一聲冷哼從身側(cè)響起空盼,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎台汇,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體励七,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡掠抬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瞳步。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腰奋。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖嘀倒,靈堂內(nèi)的尸體忽然破棺而出局冰,到底是詐尸還是另有隱情,我是刑警寧澤康二,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布沫勿,位于F島的核電站,受9級特大地震影響产雹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贝攒,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一时甚、第九天 我趴在偏房一處隱蔽的房頂上張望哈踱。 院中可真熱鬧,春花似錦刀诬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至又碌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間铸鹰,已是汗流浹背皂岔。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留剖毯,地道東北人缤苫。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像涣狗,于是被迫代替她去往敵國和親舒憾。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容