Java 中常用的資料庫連接配接池有 C3P0、Hikari、Druid 等。資料庫的連接配接池,對于整個項目的性能還是很關鍵的,是以所有的 Java 項目當中都會使用資料庫連接配接池。在 Java 的各種資料庫連接配接池中,Druid 是阿裡巴巴推出的開源的、号稱最好用資料庫連接配接池,它提供了強大的監控和擴充功能。Druid 在 github 的位址如下:
https://github.com/alibaba/druid/wiki/常見問題
本次來整理一下關于 Spring 和 Druid 的整合。
建立 SpringBoot 項目
在整合 Druid 之前,需要先建立一個 SpringBoot 和 MyBatis 的項目,先來觀察一下,它預設是否使用了資料庫連接配接池,使用了什麼資料庫連接配接池。然後,再來整合 Druid 這款資料庫連接配接池到項目當中。
建立 SpringBoot 和 Mybatis 的項目很簡單,通過向導即可完成。建立項目後的依賴如下:
org.springframework.boot spring-boot-starter-weborg.mybatis.spring.boot mybatis-spring-boot-starter 2.1.3mysql mysql-connector-java runtimeorg.springframework.boot spring-boot-starter-test testorg.junit.vintage junit-vintage-engine
其中的依賴很少,添加了 SpringMVC、Mybatis 和 MySQL。有了依賴之後,添加資料庫的配置,否則項目無法啟動。資料庫的配置如下:
spring: datasource: url: jdbc:mysql://192.168.0.106:3306/scms?serverTimezone=UTC username: root password:
有了上面的配置,項目就可以啟動了,不過整個項目沒有任何功能啟動也無意義。是以來寫一個簡單的單元測試,代碼如下:
@AutowiredDataSource dataSource;@Testvoid contextLoads() throws SQLException{ System.out.println(dataSource.getClass()); Connection connection = dataSource.getConnection(); System.out.println(connection);}
有了單元測試之後,直接運作單元測試的代碼,輸出結果如下:
class com.zaxxer.hikari.HikariDataSource2020-10-02 11:17:41.279 INFO 25817 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...2020-10-02 11:17:41.457 INFO 25817 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start [email protected] wrapping [email protected] 11:17:41.472 INFO 25817 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...2020-10-02 11:17:41.482 INFO 25817 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
可以看到,雖然在項目中沒有整合任何的資料庫連接配接池,但是 Spring 預設整合了 Hikari 這個資料庫連接配接池。但是,我們想要使用的是 Druid,那麼該如何做?
整合 Druid
整合 Druid 的方法也比較簡單的,引入 Druid 的相關依賴,并修改資料庫的配置即可。依賴如下:
com.alibaba druid 1.1.24
修改資料庫的配置隻需要增加一行配置即可,配置如下:
spring: datasource: url: jdbc:mysql://192.168.0.106:3306/scms?serverTimezone=UTC username: root password: type: com.alibaba.druid.pool.DruidDataSource
比較前面的配置,我們的配置增加了一行配置,然後我們接着運作前面的單元測試代碼。輸出如下:
class com.alibaba.druid.pool.DruidDataSource2020-10-02 12:01:18.784 INFO 26316 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} [email protected] 12:01:18.920 INFO 26316 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} closing ...2020-10-02 12:01:18.921 INFO 26316 --- [extShutdownHook] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} closed2020-10-02 12:01:18.922 INFO 26316 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
可以看到,資料庫連接配接池已經變成了 alibaba 的 Druid 了。
當然了,這不能算完,因為資料庫連接配接池還是有很多配置的,我們添加一些配置,配置如下:
spring: datasource: url: jdbc:mysql://192.168.0.106:3306/scms?serverTimezone=UTC username: root password: type: com.alibaba.druid.pool.DruidDataSource initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true
上面的配置對 Druid 進行相關的配置,但是添加上配置是否能生效,修改我們的單元測試代碼并運作,單元測試代碼修改如下:
DruidDataSource druidDataSource = (DruidDataSource)dataSource;System.out.println("initialSize: " + druidDataSource.getInitialSize());System.out.println("maxActive: " + druidDataSource.getMaxActive());
運作修改後的單元測試,檢視輸出:
initialSize: 0maxActive: 8
可以看到,并沒有按照我們的預期進行輸出,因為配置并沒有被讀取。我們需要能夠将修改的配置進行讀取。
讀取資料庫連接配接池配置
想要使用資料庫連接配接池的配置,那麼就需要定義一個讀取配置的類,并重新執行個體化一個 DataSource 類。代碼如下:
@Configurationpublic class DruidConfig{ @ConfigurationProperties(prefix = "spring.datasource") @Bean public DataSource druidDataSource() { return new DruidDataSource(); }}
再次運作單元測試,檢視輸出:
initialSize: 5maxActive: 20
可以看到,現在的輸出結果已經和配置相同了。
配置監控
在前面已經提到過,Druid 有強大的監控功能,但是需要我們進行簡單的代碼編寫才可以進行檢視具體的監控,代碼如下;
@Beanpublic ServletRegistrationBean druidServletRegistrationBean(){ ServletRegistrationBean servletServletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");; Map initParam = new HashMap<>(); //背景允許誰可以通路 initParam.put("loginUsername", "admin"); initParam.put("loginPassword", "123456"); initParam.put("allow", ""); servletServletRegistrationBean.setInitParameters(initParam); return servletServletRegistrationBean;}// 配置 Druid 監控 之 web 監控的 filter// WebStatFilter:用于配置Web和Druid資料源之間的管理關聯監控統計@Beanpublic FilterRegistrationBean webStatFilter() { FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(new WebStatFilter()); Map initParams = new HashMap<>(); initParams.put("exclusions", "*.js,*.css,/druid/*"); bean.setInitParameters(initParams); //"/*" 表示過濾所有請求 bean.setUrlPatterns(Arrays.asList("/*")); return bean;}
啟動項目,然後通路 localhost:8080/druid/ 就會進入 Druid 的監控界面,界面如下:
到此 Spring 整合 Druid 就完成了。