1.starter機制
SpringBoot中的starter是一種非常重要的機制,能夠拋棄以前繁雜的配置,將其統一集成進starter,應用者只需要在maven中引入starter依賴,SpringBoot就能自動掃描到要加載的信息並啟動相應的默認配置。starter讓我們擺脫了各種依賴庫的處理,需要配置各種信息的困擾。SpringBoot會自動通過classpath路徑下的類發現需要的Bean,並注冊進IOC容器。SpringBoot提供了針對日常企業應用研發各種場景的spring-boot-starter依賴模塊。所有這些依賴模塊都遵循着約定成俗的默認配置,並允許我們調整這些配置,即遵循“約定大於配置”的理念。
2.為什么要自定義starter
在我們的日常開發工作中,經常會有一些獨立於業務之外的配置模塊,比如對時間的處理,對字符串的處理。我們經常將其放到一個特定的包下,然后如果另一個工程需要復用這塊功能的時候,需要將代碼硬拷貝到另一個工程,重新集成一遍,麻煩至極。如果我們將這些可獨立於業務代碼之外的功配置模塊封裝成一個個starter,復用的時候只需要將其在pom中引用依賴即可,SpringBoot為我們完成自動裝配,簡直不要太爽。
3.自定義starter的案例
以下案例由筆者工作中遇到的部分場景
▲ 動態數據源。
▲ 登錄模塊。
▲ 基於AOP技術實現日志切面。
。。。。。。
4、自定義starter的命名規則
SpringBoot提供的starter以spring-boot-starter-xxx
的方式命名的。官方建議自定義的starter使用xxx-spring-boot-starter
命名規則。以區分SpringBoot生態提供的starter。
5.starter實現
1).先看目錄結構
2).pom.xml文件
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 2 <modelVersion>4.0.0</modelVersion> 3 <groupId>com.demo</groupId> 4 <artifactId>demo-spring-boot-starter</artifactId> 5 <version>0.0.1-SNAPSHOT</version> 6 <name>demo-spring-boot-starter</name> 7 <description>Demo project for Spring Boot</description> 8 9 <parent> 10 <groupId>org.springframework.boot</groupId> 11 <artifactId>spring-boot-starter-parent</artifactId> 12 <version>2.0.4.RELEASE</version> 13 </parent> 14 15 <properties> 16 <java.version>1.8</java.version> 17 </properties> 18 19 <dependencies> 20 <dependency> 21 <groupId>org.springframework.boot</groupId> 22 <artifactId>spring-boot-configuration-processor</artifactId> 23 <optional>true</optional> 24 </dependency> 25 26 <dependency> 27 <groupId>org.springframework.boot</groupId> 28 <artifactId>spring-boot-starter</artifactId> 29 </dependency> 30 </dependencies> 31 </project>
其中:spring默認使用yml中的配置,但有時候要用傳統的xml或properties配置,就需要使用spring-boot-configuration-processor依賴了。
3).定義一個實體類映射配置信息
1 @ConfigurationProperties(prefix = "demo") 2 public class DemoProperties { 3 private String sayWhat; 4 private String toWho; 5 6 public String getSayWhat() { 7 return sayWhat; 8 } 9 10 public void setSayWhat(String sayWhat) { 11 this.sayWhat = sayWhat; 12 } 13 14 public String getToWho() { 15 return toWho; 16 } 17 18 public void setToWho(String toWho) { 19 this.toWho = toWho; 20 } 21 }
4).定義一個服務service
1 public class DemoService { 2 public String sayWhat; 3 public String toWho; 4 public DemoService(String sayWhat, String toWho){ 5 this.sayWhat = sayWhat; 6 this.toWho = toWho; 7 } 8 public String say(){ 9 return this.sayWhat + "! " + toWho; 10 } 11 12 public String getString(String a) { 13 return a+"1234"; 14 } 15 }
5).定義一個配置類
1 @Configuration 2 @EnableConfigurationProperties(DemoProperties.class) 3 @ConditionalOnProperty( 4 prefix = "demo", 5 name = "isopen", 6 havingValue = "true" 7 ) 8 public class DemoConfig { 9 @Autowired 10 private DemoProperties demoProperties; 11 12 @Bean(name = "demo") 13 public DemoService demoService(){ 14 return new DemoService(demoProperties.getSayWhat(), demoProperties.getToWho()); 15 } 16 }
這里,我們將DemoService類定義為一個Bean,交給Ioc容器。
@Configuration表示這是一個配置類
@EnableConfigurationProperties 確保SpringBoot支持@ConfigurationProperties注解的Bean對象。讓springboot在初始化容器的時候,能夠也將@ConfigurationProperties注解的Bean對象初始化到容器中。
當然了,也可以在上面 DemoProperties 類上面加上@Configuration注解或者@Component注解。
@ConditionalOnProperty 注解控制 @Configuration 是否生效。簡單來說也就是我們可以通過在yml配置文件中控制 @Configuration 注解的配置類是否生效
6).spring.factories文件
1 #-------starter自動裝配--------- 2 org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.demo.starter.config.DemoConfig
在該文件中加入這個配置,該配置指定上步驟中定義的配置類為自動裝配的配置。讓springboot注解關鍵三個之一的@EnableAutoConfiguration注解去工作。
測試
1.選中項目-右擊- run as - maven install
本地倉庫中就有了我們自定義的starter依賴。
2.然后在測試項目中添加上依賴
<dependency> <groupId>com.demo</groupId> <artifactId>demo-spring-boot-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
配置文件
demo.isopen=true
demo.sayWhat=hello
demo.toWho= fengyuduke
寫個測試類
1 @RestController 2 public class HelloController { 3 @GetMapping("/hello") 4 public String hello() { 5 return "hello"; 6 } 7 8 @Autowired 9 private DemoService demoService; 10 11 @GetMapping("/say") 12 public String sayWhat(){ 13 return demoService.say(); 14 } 15 @GetMapping("/getString") 16 public String getString() { 17 return demoService.getString("風雨渡客"); 18 } 19 }
訪問測試
這時候,你如果把xml文件中的demo.isopen設置為false 或者注掉。
#demo.isopen=false demo.sayWhat=hello demo.toWho=fengyuduke
服務是起不來的,控制台報錯信息也很明顯。
Description: Field demoService in org.javaboy.formlogin.HelloController required a bean of type 'com.demo.starter.service.DemoService' that could not be found. The injection point has the following annotations: - @org.springframework.beans.factory.annotation.Autowired(required=true) The following candidates were found but could not be injected: - Bean method 'demoService' in 'DemoConfig' not loaded because @ConditionalOnProperty (demo.isopen=true) found different value in property 'isopen' Action: Consider revisiting the entries above or defining a bean of type 'com.demo.starter.service.DemoService' in your configuration.
(非原創)參考鏈接:https://www.cnblogs.com/hello-shf/p/10864977.html