資料訪問之Druid啟動器的使用
官方文件:
首先在在 Spring Boot 專案中加入
druid-spring-boot-starter
依賴 。
博主版本:1.1.17 SpriongBoot:2.5.3
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>版本號</version>
</dependency>
我們來看下Druid中的自動配置(兩種方式):
- 可以雙擊shift開啟搜尋找到DruidDataSourceAutoConfigure
原始碼分析:
為什麼匯入啟動器就能使用Druid資料來源。
@Configuration
@ConditionalOnClass(DruidDataSource.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties({DruidStatProperties.class, DataSourceProperties.class})
@Import({DruidSpringAopConfiguration.class,
DruidStatViewServletConfiguration.class,
DruidWebStatFilterConfiguration.class,
DruidFilterConfiguration.class})
public class DruidDataSourceAutoConfigure {
private static final Logger LOGGER = LoggerFactory.getLogger(DruidDataSourceAutoConfigure.class);
@Bean(initMethod = "init")
@ConditionalOnMissingBean
public DataSource dataSource() {
LOGGER.info("Init DruidDataSource");
return new DruidDataSourceWrapper();
}
}
看以下兩個註解:
@ConditionalOnClass(DruidDataSource.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
- 當容器中有這個類
- 後面的內容在這個類(DataSourceAutoConfiguration.class)之前執行
為什麼這樣設定呢?
進入DataSourceAutoConfiguration類後找到引入的DataSourceConfiguration.Hikari.class,。
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HikariDataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
matchIfMissing = true)
static class Hikari {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
HikariDataSource dataSource(DataSourceProperties properties) {
HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
if (StringUtils.hasText(properties.getName())) {
dataSource.setPoolName(properties.getName());
}
return dataSource;
}
}
由上述程式碼可以發現,預設的配置源是HikariDataSource,但是有一個要求:
@ConditionalOnMissingBean(DataSource.class)
就是如果在容器中沒有資料來源,下面程式碼生效,也就是使用HikariDataSource,但是若容器中已經有開發者建立的資料來源,那麼開發者建立的優先。
所以Druid的建立必須要在預設源之前宣告,如果在預設源之後宣告,Druid資料來源將不生效,由於Druid的自動配置決定的:
@ConditionalOnMissingBean
public DataSource dataSource() {
LOGGER.info("Init DruidDataSource");
return new DruidDataSourceWrapper();
}
ConditionalOnMissingBean:容器中已經有了預設源的話,那麼Druid的源是不生效的。
功能實現介紹:
檢視具體的功能只要分析它匯入了哪些類就能明白它所實現的功能。
- DruidSpringAopConfiguration.class,
- DruidStatViewServletConfiguration.class,
- DruidWebStatFilterConfiguration.class,
- DruidFilterConfiguration.class
DruidSpringAopConfiguration對應功能
該類是配置Spring的監控的,點選進入,可以看到相關的設定:
@Bean
@ConditionalOnProperty(name = "spring.aop.auto",havingValue = "false")
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
與我們手動配置的如出一轍,不明白的朋友可以簡單瞭解z下之前的文章:
通過該類上的屬性配置進行屬性繫結,@ConditionalOnProperty("spring.datasource.druid.aop-patterns")
配置項:spring.datasource.druid.aop-patterns
所以我們可以在application.yaml檔案中配置Springd監控的功能。
DruidStatViewServletConfiguration
該類是實現開啟監控頁的功能,相當於我們之前寫的StatViewServlet
自定義寫法:
/**
* 配置監控頁
*/
@Bean
public ServletRegistrationBean staViewServlet(){
//例項化StatViewServlet
StatViewServlet statViewServlet = new StatViewServlet();
//將例項化的例項化StatViewServlet 傳入ServletRegistrationBean,並設定訪問路徑
ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");
return registrationBean;
}
Druid-start中的配置:
基本上也是如出一轍,自定義的功能比較單一。
所以我們使用Druid-start來簡化我們之前的操作,可以通過DruidStatViewServletConfiguration中的配置屬性配置:
@ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true")
配置項:spring.datasource.druid.stat-view-servlet.enabled。
擴充套件(havingValue):
@ConditionalOnProperty,這個註解能夠控制某個configuration是否生效。具體操作是通過其兩個屬性name以及havingValue來實現的,其中name用來從application.properties中讀取某個屬性值,如果該值為空,則返回false;如果值不為空,則將該值與havingValue指定的值進行比較,如果一樣則返回true;否則返回false。如果返回值為false,則該configuration不生效;為true則生效
通過上述文章的所說,SpringBoot首先會去spring.datasource.druid.stat-view-servlet該配置項中找到enabled的值是什麼,如果該值與havingValue指定的值進行比較,一樣則返回true,這樣該Bean就會生效,也就是該元件或者功能開啟。在配置檔案中我們設定後可以佐證該結論是否正確。
後面兩個類也基本是相同的方法,各位自行檢視,在此省略。
DruidWebStatFilterConfiguration //web應用開啟DruidFilterConfiguration //Filter開啟
開啟配置屬性:
配置必須屬性:
spring: datasource: url: jdbc:mysql://localhost:3306/vuesite username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver
開啟監控頁:
開啟監控頁也就是增加StatViewServlet元件。
spring: datasource: url: jdbc:mysql://localhost:3306/vuesite username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver druid: stat-view-servlet: enabled: true
我們看一下enabled的預設配置,點選enabled,找到私有屬性可知:
/** * Enable StatViewServlet, default false. */private boolean enabled;
預設為false,這也就佐證了上述的結論。
完整的yaml基本配置如下:
spring: datasource: url: jdbc:mysql://localhost:3306/vuesite username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver druid: aop-patterns: com.xbhog.* filters: stat,wall # 底層開啟功能,stat(sql監控),wall(防火牆) stat-view-servlet: # 配置監控頁功能 enabled: true login-username: admin login-password: admin resetEnable: false web-stat-filter: # 監控web enabled: true urlPattern: /* exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*' filter: stat: #對上面filters裡面的stat的詳細配置 slow-sql-millis: 1000 logSlowSql: true enabled: true wall: enabled: true config: drop-table-allow: false
因為我們監控主要事情是sql,所以測試功能的時候需要傳送一個controller sql.如下程式碼:
@Controllerpublic class Mycontro { @Autowired JdbcTemplate jdbcTemplate; @ResponseBody //不經過檢視解析器 @GetMapping("/sql") public String druidquery(){ Long aLong = jdbcTemplate.queryForObject("select count(*) from user",Long.class); return aLong.toString(); }}
在配置的時候出現的錯誤
aop-patterns配置好以後,開啟介面重新整理,發現並沒有生效,也就是沒有監控到。
在網上找了很多方法,也看了官方文件,還是不行。
最後使用了原始的方法,降版本號,親測在 Druid在1.1.17可以使用。
參考:
SpringBoot2零基礎入門springboot全套完整版
結束:
如果你看到這裡或者正好對你有所幫助,希望能點個關注或者推薦,感謝;
有錯誤的地方,歡迎在評論指出,作者看到會進行修改。