實戰|如何自定義SpringBoot Starter?

後端進階發表於2019-05-11

SpringBoot自動化配置原始碼分析從原始碼的角度講解了 SpringBoot 自動化配置的原理,知道了它最終要乾的事情不過是讀取 META-INF/spring.factories 中的自動化配置類而已。

SpringBoot 專案就是由一個一個 Starter 組成的,一個 Starter 代表該專案的 SpringBoot 起步依賴,除了官方已有的 Starter,如果你需要將自己的專案支援 SpringBoot,那麼就需要把它製作成一個 Starter。這篇部落格依據 SpringBoot 的自動化配置原理,開發一個屬於自己的 Starter。

自定義 Starter

自動化配置需滿足兩個條件:

  1. 能夠生成 Bean,並註冊到 Bean 容器中;
  2. 能夠自動配置專案所需要的配置。

在這裡建立一個 spring-boot-starter-helloworld 專案作為例子,實現以上兩點。

引入 SpringBoot 自動化配置依賴:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>1.5.9.RELEASE</version>
  </dependency>
</dependencies>
複製程式碼

spring-boot-starter-helloworld 只是作為例子演示自定義 starter 的過程,實現的功能很簡單就是建立一個 HelloworldService 的,並配置 sayHello() 方法列印的語句。

public class HelloworldService {

  private String words;

  private String getWords() {
    return words;
  }

  public void setWords(String words) {
    this.words = words;
  }

  public String sayHello() {
     return "hello, " + words;
  }
}
複製程式碼

建立屬性類,prefix = "helloworld"代表該專案在屬性檔案中配置的字首,即可以在屬性檔案中通過 helloworld.words=springboot,就可以改變屬性類欄位 words 的值了。

@ConfigurationProperties(prefix = "helloworld")
public class HelloworldProperties {
  public static final String DEFAULT_WORDS = "world";

  private String words = DEFAULT_WORDS;

  public String getWords() {
    return words;
  }

  public void setWords(String words) {
    this.words = words;
  }
}
複製程式碼

建立自動化配置類,這個相當於就是一個普通的 Java 配置類,可以在這裡建立 Bean,並可獲得與 application.properties 屬性檔案相對應的屬性類的 Bean。

// 相當於一個普通的 java 配置類
@Configuration
// 當 HelloworldService 在類路徑的條件下
@ConditionalOnClass({HelloworldService.class})
// 將 application.properties 的相關的屬性欄位與該類一一對應,並生成 Bean
@EnableConfigurationProperties(HelloworldProperties.class)
public class HelloworldAutoConfiguration {

  // 注入屬性類
  @Autowired
  private HelloworldProperties hellowordProperties;

  @Bean
  // 當容器沒有這個 Bean 的時候才建立這個 Bean
  @ConditionalOnMissingBean(HelloworldService.class)
  public HelloworldService helloworldService() {
    HelloworldService helloworldService = new HelloworldService();
    helloworldService.setWords(hellowordProperties.getWords());
    return helloworldService;
  }
}
複製程式碼

在 META-INF 目錄下建立 spring.factories,這個屬性檔案可重要啦,因為 SpringBoot 自動化配置最終就是要掃描 META-INF/spring.factories 來載入專案的自動化配置類。

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.objcoding.starters.helloworld.HelloworldAutoConfiguration
複製程式碼

引用 Starter

為了引入 starter,我在這裡再建立一個 spring-boot-starter-helloworld-sample 專案。

新增 spring-boot-starter-helloworld 起步依賴:

<dependency>
  <groupId>com.objcoding</groupId>
  <artifactId>spring-boot-starter-helloworld</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>
複製程式碼

在 application.properties 中新增屬性:

helloworld.words=springboot
複製程式碼

在 SpringBoot 主程式中 注入 helloworldService

@RestController
@SpringBootApplication
public class HelloworldApplication {

  @Autowired
  private HelloworldService helloworldService;

  @RequestMapping("/")
  public String sayHello() {
    return helloworldService.sayHello();
  }

  public static void main(String[] args) {
    SpringApplication.run(HelloworldApplication.class, args);
  }
}
複製程式碼

訪問 http://localhost:8080/,列印以下結果:

hello, springboot

要原始碼的同學點選這裡獲取: github.com/objcoding/s…

公眾號「後端進階」,專注後端技術分享!

相關文章