SpringBoot資料訪問之Druid啟動器的使用

xbhog發表於2021-08-07

資料訪問之Druid啟動器的使用

承接上文:SpringBoot資料訪問之Druid資料來源的自定義使用

官方文件:

Druid Spring Boot Starter

首先在在 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中的自動配置(兩種方式):

  1. 可以雙擊shift開啟搜尋找到DruidDataSourceAutoConfigure
  2. image-20210806161823666

原始碼分析:

為什麼匯入啟動器就能使用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)
  1. 當容器中有這個類
  2. 後面的內容在這個類(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對應功能

image-20210806170156460

該類是配置Spring的監控的,點選進入,可以看到相關的設定:

@Bean
@ConditionalOnProperty(name = "spring.aop.auto",havingValue = "false")
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
    advisorAutoProxyCreator.setProxyTargetClass(true);
    return advisorAutoProxyCreator;
}

與我們手動配置的如出一轍,不明白的朋友可以簡單瞭解z下之前的文章:

  1. 掘金: SpringBoot資料訪問之自定義Druid
  2. 個人部落格:SpringBoot資料訪問之自定義Druid

通過該類上的屬性配置進行屬性繫結,@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中的配置:

image-20210806171124269

基本上也是如出一轍,自定義的功能比較單一。

所以我們使用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可以使用。

image-20210806215242510

參考:

havingValue

Druid Spring Boot Starter

SpringBoot2零基礎入門springboot全套完整版

結束:

如果你看到這裡或者正好對你有所幫助,希望能點個關注或者推薦,感謝;

有錯誤的地方,歡迎在評論指出,作者看到會進行修改。

相關文章