Spring Boot 整合多點套路,少走點彎路~

愛撒謊的男孩發表於2020-10-19

持續原創輸出,點選上方藍字關注我

個人原創部落格+1,點選前往,檢視更多

目錄

  • 前言
  • Spring Boot 版本
    1. 找到自動配置類
    1. 注意@Conditionalxxx註解
    1. 注意EnableConfigurationProperties註解
    1. 注意@Import註解
    1. 注意@AutoConfigurexxx註解
    1. 注意內部靜態配置類
  • 總結

前言

網上有很多文章都在說Spring Boot 如何整合 xxx,有文章教你為什麼這麼整合嗎?整合了千萬個框架,其實套路就那麼幾個,幹嘛要學千萬個,不如來這學習幾個套路輕鬆整合,它不香嗎???

今天寫這篇文章的目的就是想從思想上教給大家幾個套路,不用提到整合什麼就去百度了,自己嘗試去親手整合一個。

Spring Boot 版本

本文基於的Spring Boot的版本是2.3.4.RELEASE

1. 找到自動配置類

Spring Boot 在整合任何一個元件的時候都會先新增一個依賴starter,比如整合的Mybatis有一個mybatis-spring-boot-starter,依賴如下:

<dependency>
         <groupId>org.mybatis.spring.boot</groupId>
         <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.0.0</version>
</dependency>

每一個starter基本都會有一個自動配置類,命名方式也是類似的,格式為:xxxAutoConfiguration,比如Mybatis的自動配置類就是MybatisAutoConfigurationRedis的自動配置類是RedisAutoConfigurationWEB模組的自動配置類是WebMvcAutoConfiguration

2. 注意@Conditionalxxx註解

@Conditionalxxx標註在配置類上或者結合@Bean標註在方法上,究竟是什麼意思,在上一篇文章這類註解都不知道,還好意思說會Spring Boot已經從表層到底層深入的講了一遍,不理解的可以查閱一下。

首先需要注意自動配置類上的@Conditionalxxx註解,這個是自動配置類生效的條件。

比如WebMvcAutoConfiguration類上標了一個如下註解:

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

以上這行程式碼的意思就是當前IOC容器中沒有WebMvcConfigurationSupport這個類的例項時自動配置類才會生效,這也就是在配置類上標註@EnableWebMvc會導致自動配置類WebMvcAutoConfiguration失效的原因。

其次需要注意方法上的@Conditionalxxx註解,Spring Boot會在自動配置類中結合@Bean@Conditionalxxx註解提供一些元件執行的預設配置,但是利用@Conditionalxxx(在特定條件下生效)註解的條件性,方便開發者覆蓋這些配置。

比如在Mybatis的自動配置類MybatisAutoConfiguration中有如下一個方法:

  @Bean
  @ConditionalOnMissingBean
  public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {}

以上這個方法不用看方法體的內容,只看方法上的註解。@Bean這個註解的意思是注入一個BeanIOC容器中,@ConditionalOnMissingBean這個註解就是一個條件判斷了,表示當SqlSessionFactory型別的物件在IOC容器中不存在才會注入。

哦?領悟到了吧,言外之意就是如果開發者需要定製SqlSessionFactory,則可以自己的建立一個SqlSessionFactory型別的物件並且注入到IOC容器中即能覆蓋自動配置類中的。比如在Mybatis配置多資料來源的時候就需要定製一個SqlSessionFactory而不是使用自動配置類中的。

總之,一定要注意自動配置類上或者方法上的@Conditionalxxx註解,這個註解表示某種特定條件。

下面列出了常用的幾種註解,如下:

  1. @ConditionalOnBean:當容器中有指定Bean的條件下進行例項化。
  2. @ConditionalOnMissingBean:當容器裡沒有指定Bean的條件下進行例項化。
  3. @ConditionalOnClass:當classpath類路徑下有指定類的條件下進行例項化。
  4. @ConditionalOnMissingClass:當類路徑下沒有指定類的條件下進行例項化。
  5. @ConditionalOnWebApplication:當專案是一個Web專案時進行例項化。
  6. @ConditionalOnNotWebApplication:當專案不是一個Web專案時進行例項化。
  7. @ConditionalOnProperty:當指定的屬性有指定的值時進行例項化。
  8. @ConditionalOnExpression:基於SpEL表示式的條件判斷。
  9. @ConditionalOnJava:當JVM版本為指定的版本範圍時觸發例項化。
  10. @ConditionalOnResource:當類路徑下有指定的資源時觸發例項化。
  11. @ConditionalOnJndi:在JNDI存在的條件下觸發例項化。
  12. @ConditionalOnSingleCandidate:當指定的Bean在容器中只有一個,或者有多個但是指定了首選的Bean時觸發例項化。

3. 注意EnableConfigurationProperties註解

EnableConfigurationProperties這個註解常標註在配置類上,使得@ConfigurationProperties標註的配置檔案生效,這樣就可以在全域性配置檔案(application.xxx)配置指定字首的屬性了。

在Redis的自動配置類RedisAutoConfiguration上方標註如下一行程式碼:

@EnableConfigurationProperties(RedisProperties.class)

這行程式碼有意思了,我們可以看看RedisProperties的原始碼,如下:

@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
 private int database = 0;
 private String url;
 private String host = "localhost";
 private String password;
  .....

@ConfigurationProperties這個註解指定了全域性配置檔案中以spring.redis.xxx為字首的配置都會對映到RedisProperties的指定屬性中,其實RedisProperties這個類中定義了Redis的一些所需屬性,比如hostIP地址密碼等等。

@EnableConfigurationProperties註解就是使得指定的配置生效,能夠將全域性配置檔案中配置的屬性對映到相關類的屬性中。

為什麼要注意@EnableConfigurationProperties這個註解呢?

引入一個元件後往往需要改些配置,我們都知道在全域性配置檔案中可以修改,但是不知道字首是什麼,可以改哪些屬性,因此找到@EnableConfigurationProperties這個註解後就能找到對應的配置字首以及可以修改的屬性了。

4. 注意@Import註解

這個註解有點牛逼了,Spring 3.x中就已經有的一個註解,大致的意思的就是快速匯入一個Bean或者配置類到IOC容器中。這個註解有很多妙用,後續會單獨寫篇文章介紹下。

@Import這個註解通常標註在自動配置類上方,並且一般都是匯入一個或者多個配置類。

比如RabbitMQ的自動配置類RabbitAutoConfiguration上有如下一行程式碼:

@Import(RabbitAnnotationDrivenConfiguration.class)

這行程式碼的作用就是新增了RabbitAnnotationDrivenConfiguration這個配置類,使得Spring Boot在載入到自動配置類的時候能夠一起載入。

比如Redis的自動配置類RedisAutoConfiguration上有如下一行程式碼:

@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })

這個@Import同時引入了LettuceJedis兩個配置類了,因此如果你的Redis需要使用Jedis作為連線池的話,想要知道Jedis都要配置什麼,此時就應該看看JedisConnectionConfiguration這個配置類了。

總結@Import標註在自動配置類上方,一般都是快速匯入一個或者多個配置類,因此如果自動配置類沒有配置一些東西時,一定要看看@Import這個註解匯入的配置類。

5. 注意@AutoConfigurexxx註解

@AutoConfigurexxx這類註解決定了自動配置類的載入順序,比如AutoConfigureAfter(在指定自動配置類之後)、AutoConfigureBefore(在指定自動配置類之前)、AutoConfigureOrder(指定自動配置類的優先順序)。

為什麼要注意順序呢?因為某些元件往往之間是相互依賴的,比如MybatisDataSource,肯定要先將資料來源相關的東西配置成功才能配置Mybatis吧。@AutoConfigurexxx這類註解正是解決了元件之間相互依賴的問題。

比如MybatisAutoConfiguration上方標註瞭如下一行程式碼:

@AutoConfigureAfter(DataSourceAutoConfiguration.class)

這個行程式碼意思很簡單,就是MybatisAutoConfiguration這個自動配置在DataSourceAutoConfiguration這個之後載入,因為你需要我,多麼簡單的理由。

好了,這下明白了吧,以後別犯傻問:為什麼Mybatis配置好了,啟動會報錯?這個問題先看看資料來源有沒有配置成功吧。

6. 注意內部靜態配置類

有些自動配置類比較簡單沒那麼多套路,比如RedisAutoConfiguration這個自動配置類中就定義了兩個注入Bean的方法,其他的沒了。

但是有些自動配置類就沒那麼單純了,中間能巢狀n個靜態配置類,比如WebMvcAutoConfiguration,類中還巢狀了WebMvcAutoConfigurationAdapterEnableWebMvcConfigurationResourceChainCustomizerConfiguration這三個配置類。如果你光看WebMvcAutoConfiguration這個自動配置類好像沒配置什麼,但是其內部卻是大有乾坤啊。

總結:一定要自動配置類的內部巢狀的配置類,真是大有乾坤啊。

總結

以上總結了六條整合的套路,希望能夠幫助讀者擺脫百度,自己也能獨立整合元件。

總之,Spring Boot整合xxx元件的文章很多,相信大家也看的比較懵,其實套路都是一樣,學會陳某分享的套路,讓你少走彎路!!!

相關文章