詳解SpringBoot如何自定義自己的Starter組件
一、為什么要自定義starter
在我們的日常開(kāi)發(fā)工作中,經(jīng)常會(huì)有一些獨(dú)立于業(yè)務(wù)之外的配置模塊,我們經(jīng)常將其放到一個(gè)特定的 包下,然后如果另一個(gè)工程需要復(fù)用這塊功能的時(shí)候,需要將代碼硬拷貝到另一個(gè)工程,重新集成一 遍,麻煩至極。如果我們將這些可獨(dú)立于業(yè)務(wù)代碼之外的功能配置模塊封裝成一個(gè)個(gè)starter,復(fù)用的時(shí) 候只需要將其在pom中引用依賴即可,SpringBoot為我們完成自動(dòng)裝配,簡(jiǎn)直不要太爽。
二、starter的實(shí)現(xiàn)
雖然不同的starter
實(shí)現(xiàn)起來(lái)各有差異,但是他們基本上都會(huì)使用到兩個(gè)相同的內(nèi)容:ConfigurationProperties
和AutoConfiguration
。因?yàn)?code>Spring Boot堅(jiān)信“約定大于配置”這一理念,所以我們使用ConfigurationProperties來(lái)保存我們的配置,并且這些配置都可以有一個(gè)默認(rèn)值,即在我們沒(méi)有主動(dòng)覆寫原始配置的情況下,默認(rèn)值就會(huì)生效,這在很多情況下是非常有用的。除此之外,starter
的ConfigurationProperties
還使得所有的配置屬性被聚集到一個(gè)文件中(一般在resources目錄下的application.properties),這樣我們就告別了Spring項(xiàng)目中XML地獄。
三、命名規(guī)范
如果你快有孩子了,出生前你比較急的一定是起個(gè)名字。孩子的姓名標(biāo)識(shí)著你和你愛(ài)人的血統(tǒng),一定不會(huì)起隔壁老王的姓氏,肯定會(huì)招來(lái)異樣的眼光。在maven
中,groupId
代表著姓氏,artifactId
代表著名字。Spring Boot
也是有一個(gè)命名的建議的。所以名字是不能夠隨隨便便取得,可以按照官方的建議來(lái)取。
What’s in a name All official starters follow a similar naming pattern; spring-boot-starter-, whereis a particular type of application. This naming structure is intended to help when you need to find a starter. The Maven integration in many IDEs lets you search dependencies by name. For example, with the appropriate Eclipse or STS plugin installed, you can press ctrl-space in the POM editor and type “spring-boot-starter” for a complete list. As explained in the “Creating Your Own Starter” section, third party starters should not start with spring-boot, as it is reserved for official Spring Boot artifacts. Rather, a third-party starter typically starts with the name of the project. For example, a third-party starter project called thirdpartyproject would typically be named thirdpartyproject-spring-boot-starter.
大概意思:官方的 starter
的命名格式為 spring-boot-starter-{xxxx}
比如spring-boot-starter-activemq,
第三方我們自己的命名格式為 {xxxx}-spring-boot-starter
。比如mybatis-spring-boot-starter
。如果我們忽略這種約定,是不是會(huì)顯得我們寫的東西不夠“專業(yè)“。
四、代碼工程
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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"> <parent> <artifactId>springboot-demo</artifactId> <groupId>com.et</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>xxx-spring-boot-starter</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> </dependencies>
屬性文件
com.person.age=23 com.person.name=Lynch com.person.sex=F
自動(dòng)配置類
package com.et.config; import com.et.service.PersonService; import com.et.starter.PersonProperties; 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) @ConditionalOnClass(PersonService.class) @ConditionalOnProperty(prefix = "com.person", value = "enabled", matchIfMissing = true) public class PersonServiceAutoConfiguration { @Autowired private PersonProperties properties; // if spring container do not config bean,auto config PersonService @Bean @ConditionalOnMissingBean(PersonService.class) public PersonService personService(){ PersonService personService = new PersonService(properties); return personService; } }
service類
package com.et.service; import com.et.starter.PersonProperties; public class PersonService { private PersonProperties properties; public PersonService() { } public PersonService(PersonProperties properties) { this.properties = properties; } public void sayHello() { String message = String.format("hi,my name: %s, today,I'am %s , gender: %s", properties.getName(), properties.getAge(), properties.getSex()); System.out.println(message); } }
PersonProperties
package com.et.starter; import java.io.Serializable; import org.springframework.boot.context.properties.ConfigurationProperties; @SuppressWarnings("serial") @ConfigurationProperties(prefix = "com.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; } }
spring.factories文件
/META-INF/spring.factories文件放在/src/main/resources目錄下 注意:META-INF是自己手動(dòng)創(chuàng)建的目錄,spring.factories也是自己手動(dòng)創(chuàng)建的文件,在該文件中配置自己的自動(dòng)配置類。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.et.config.PersonServiceAutoConfiguration
項(xiàng)目打包
mvn clean install
代碼倉(cāng)庫(kù)
github.com/Harries/springboot-demo
五、測(cè)試
在另外一個(gè)項(xiàng)目中添加starter的依賴
<dependency> <groupId>com.et</groupId> <artifactId>xxx-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
單元測(cè)試類
package com.et.starter; import com.et.service.PersonService; 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; @RunWith(SpringRunner.class) @SpringBootTest public class PersonServiceTest { @Autowired private PersonService personService; @Test public void testHelloWorld() { personService.sayHello(); } }
運(yùn)行測(cè)試類
2024-03-11 10:35:18.374 INFO 10960 --- [ main] com.et.starter.PersonServiceTest : Starting PersonServiceTest on BJDPLHHUAPC with PID 10960 (started by Dell in D:\IdeaProjects\ETFramework\xxx-spring-boot-starter-test)
2024-03-11 10:35:18.376 INFO 10960 --- [ main] com.et.starter.PersonServiceTest : No active profile set, falling back to default profiles: default
2024-03-11 10:35:19.387 INFO 10960 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2024-03-11 10:35:19.657 INFO 10960 --- [ main] com.et.starter.PersonServiceTest : Started PersonServiceTest in 1.507 seconds (JVM running for 2.188)
hi,my name: Lynch, today,I'am 23 , gender: F
2024-03-11 10:35:19.827 INFO 10960 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
以上就是詳解SpringBoot如何自定義自己的Starter組件的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot自定義Starter組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
細(xì)數(shù)Java接口的概念、分類及與抽象類的區(qū)別
下面小編就為大家?guī)?lái)一篇細(xì)數(shù)Java接口的概念、分類及與抽象類的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11解決IDEA中Maven依賴包導(dǎo)入失敗報(bào)紅問(wèn)題(總結(jié)最有效8種解決方案)
這篇文章主要介紹了解決IDEA中Maven依賴包導(dǎo)入失敗報(bào)紅問(wèn)題,本文通過(guò)圖文詳解給大家總結(jié)了最有效的8種解決方法,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07Event?Sourcing事件溯源模式優(yōu)化業(yè)務(wù)系統(tǒng)
這篇文章主要為大家介紹了Event?Sourcing事件溯源模式優(yōu)化業(yè)務(wù)系統(tǒng)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07SpringMVC中轉(zhuǎn)發(fā)與重定向的區(qū)別淺析
這篇文章主要給大家介紹了關(guān)于SpringMVC中轉(zhuǎn)發(fā)與重定向的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12SpringCloud Alibaba使用Seata處理分布式事務(wù)的技巧
在傳統(tǒng)的單體項(xiàng)目中,我們使用@Transactional注解就能實(shí)現(xiàn)基本的ACID事務(wù)了,隨著微服務(wù)架構(gòu)的引入,需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行分庫(kù)分表,每個(gè)服務(wù)擁有自己的數(shù)據(jù)庫(kù),這樣傳統(tǒng)的事務(wù)就不起作用了,那么我們?nèi)绾伪WC多個(gè)服務(wù)中數(shù)據(jù)的一致性呢?跟隨小編一起通過(guò)本文了解下吧2021-06-06Java函數(shù)式編程(一):你好,Lambda表達(dá)式
這篇文章主要介紹了Java函數(shù)式編程(一):你好,Lambda表達(dá)式,本文講解了新老函數(shù)式編程的一些變化,需要的朋友可以參考下2014-09-09IDEA中啟動(dòng)多個(gè)SpringBoot服務(wù)的實(shí)現(xiàn)示例
本文主要介紹了IDEA中啟動(dòng)多個(gè)SpringBoot服務(wù)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08