自定義starter
SpringBoot中的starter是一種非常重要的機制,能夠拋棄以前繁雜的配置,將其統一集成進 starter,應用者只需要在maven中引入starter依賴,SpringBoot就能自動掃描到要加載的信息並啟 動相應的默認配置。starter讓我們擺脫了各種依賴庫的處理,需要配置各種信息的困擾。 SpringBoot會自動通過classpath路徑下的類發現需要的Bean,並注冊進IOC容器。SpringBoot提供 了針對日常企業應用研發各種場景的spring-boot-starter依賴模塊。所有這些依賴模塊都遵循着約定 成俗的默認配置,並允許我們調整這些配置,即遵循“約定大於配置”的理念。
為什么要自定義starter
在我們的日常開發工作中,經常會有一些獨立於業務之外的配置模塊,我們經常將其放到一個特定的 包下,然后如果另一個工程需要復用這塊功能的時候,需要將代碼硬拷貝到另一個工程,重新集成一 遍,麻煩至極。如果我們將這些可獨立於業務代碼之外的功能配置模塊封裝成一個個starter,復用的時 候只需要將其在pom中引用依賴即可,SpringBoot為我們完成自動裝配,簡直不要太爽。
自定義starter的命名規則
SpringBoot提供的starter以spring-boot-starter-xxx的方式命名的。官方建議自定義的starter使用 xxx-spring-boot-starter命名規則。以區分SpringBoot生態提供的starter。
有了以上的了解后,來創建 Maven 項目,目錄結構如下:
1、添加pom.xml依賴(根據組件功能添加)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.0.0.RELEASE</version>
<optional>true</optional>
</dependency>
</dependencies>
2、PersonProperties.java——屬性配置類
在使用Spring官方的Starter時通常可以在application.properties中來配置參數覆蓋掉默認的值。即sex的值會被配置文件中的值替換掉。
package com.lynch.config; import java.io.Serializable; import org.springframework.boot.context.properties.ConfigurationProperties; @SuppressWarnings("serial") @ConfigurationProperties(prefix = "lynch.person") public class PersonProperties implements Serializable { // 姓名
private String name; // 年齡
private int age; // 性別
private String sex = "M"; public PersonProperties() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
3、PersonService.java——業務操作類
package com.lynch.config; public class PersonService { private PersonProperties properties; public PersonService() { } public PersonService(PersonProperties properties) { this.properties = properties; } public void sayHello() { String message = String.format("大家好,我叫: %s, 今年 %s歲, 性別: %s", properties.getName(), properties.getAge(), properties.getSex()); System.out.println(message); } }
4、PersonServiceAutoConfiguration.java類
package com.lynch.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @EnableConfigurationProperties(PersonProperties.class) //當類路徑下有指定的類為true
@ConditionalOnClass(PersonService.class) @ConditionalOnProperty(prefix = "lynch.person", value = "enabled", matchIfMissing = true) public class PersonServiceAutoConfiguration { @Autowired private PersonProperties properties; // 當容器中沒有指定Bean的情況下,自動配置PersonService類
@Bean @ConditionalOnMissingBean(PersonService.class) public PersonService personService(){ PersonService personService = new PersonService(properties); return personService; } }
5、spring.factories文件
/META-INF/spring.factories文件放在/src/main/resources目錄下
注意:META-INF是自己手動創建的目錄,spring.factories也是自己手動創建的文件,在該文件中配置自己的自動配置類。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.lynch.config.PersonServiceAutoConfiguration
6、最后,將項目打包 mvn clean install
7、在另一個項目中添加引用
7.1、添加依賴
<dependency>
<groupId>com.lynch</groupId>
<artifactId>hellostarter</artifactId>
<version>1.0</version>
</dependency>
7.2、配置application.properties
lynch.person.age=23 lynch.person.name=Lynch lynch.person.sex=F
7.3、啟動單元測試類
package com.lynch.service; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import com.lynch.config.PersonService; @RunWith(SpringRunner.class) @SpringBootTest public class PersonServiceTest { @Autowired private PersonService personService; @Test public void testHelloWorld() { personService.sayHello(); } }
2020-08-04 21:37:26.699 INFO 14468 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-04 21:37:27.521 INFO 14468 --- [ main] com.lynch.service.PersonServiceTest : Started PersonServiceTest in 2.983 seconds (JVM running for 4.071) 大家好,我叫: Lynch, 今年 23歲, 性別: F