上篇文章《每天用SpringBoot,它的自動裝配原理卻說不出來》咱們有說springBoot
的自動裝配怎麼實現的(建議最好先看下篇文章,由於先後有關係),這篇文章的話咱們就本身來實現一個SpringBoot
的 starter
吧。廢話很少說咱們仍是直入主題吧。
什麼是Spring Boot Starter
呢?咱們直接來看看官網是怎麼介紹的吧。html
Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, include the spring-boot-starter-data-jpa dependency in your project.java
納尼,一大堆的英文,這還有興趣接着往下看嗎?是否是看到這直接退出了。都到門口了,不進來喝杯茶再走嘛?看都看到這了仍是接着繼續往下看吧。咱們先不解釋這一段話是什麼意思,咱們能夠看看starter
的出現給咱們解決了什麼問題。
咱們仍是以上述官網的例子來進行說明好比說咱們須要在Spring
中適應JPA
來操做數據庫。
在沒有springBoot-starter
以前,咱們須要引入jpa
的步驟git
maven
引入jdbc的依賴、以及jpa相關的各類依賴jpa
相關的配置文件jar
包衝突啊,這個jar
包下載不下來,缺乏某個jar
包。jpa
遇到的問題,以及整合的步驟都一一的詳細記錄下來。方便下次在須要整合jpa
的時候直接copy
就行了。starter
以前是否是都是這麼玩的。這樣的缺點是否是也很是顯著,好比過程複雜、須要不停的粘貼複製(不過這是程序員常常乾的事情了,也不在意多一兩次了)、整合其它組件到本身的項目變的困難,效率低下。這也就形成了996
的程序員比較多了(晚上就不可以回去69
了)。咱們能夠看下SpringBoot
如今都爲咱們提供有哪些starter
,我這邊這截圖了部分starter
,更多的請點擊https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters
starter
的實現:雖然咱們每一個組件的starter
實現各有差別,可是它們基本上都會使用到兩個相同的內容:ConfigurationProperties
和AutoConfiguration
。由於Spring Boot
提倡「約定大於配置」這一理念,因此咱們使用ConfigurationProperties
來保存咱們的配置,而且這些配置均可以有一個默認值,即在咱們沒有主動覆寫原始配置的狀況下,默認值就會生效。除此以外,starter
的ConfigurationProperties
還使得全部的配置屬性被彙集到一個文件中(通常在resources
目錄下的application.properties
),這樣咱們就告別了Spring
項目中XML
地獄。
starter
的出現幫把咱們把各類複雜的配置都封裝起來了,讓咱們真正的能夠達到了開箱即用。不只下降了咱們使用它的門檻,而且還大大提升了咱們的開發效率。正如前面所說《SpringBoot自動裝配》讓咱們有更多的時間去陪女友。程序員
若是你快有孩子了,出生前你比較急的必定是起個名字。孩子的姓名標識着你和你愛人的血統,必定不會起隔壁老王的姓氏,確定會招來異樣的眼光。在maven
中,groupId
表明着姓氏,artifactId
表明着名字。Spring Boot
也是有一個命名的建議的。因此名字是不可以隨隨便便取得,能夠按照官方的建議來取。github
What’s in a name
All official starters follow a similar naming pattern; spring-boot-starter-*, where * is 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.spring
大概意思是
官方的 starter
的命名格式爲 spring-boot-starter-{xxxx}
好比spring-boot-starter-activemq
第三方咱們本身的命名格式爲 {xxxx}-spring-boot-starter
。好比mybatis-spring-boot-starter
。
若是咱們忽略這種約定,是否是會顯得咱們寫的東西不夠「專業「。數據庫
下面咱們就來實現一個自定義的發送短信的starter,命名爲sms-spring-boot-starter
。json
pom
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> <scope>provided</scope> </dependency>
發短信咱們須要配置一些帳號信息,不一樣的短信供應商,帳戶信息是不同的,因此咱們須要定義一個XXXXProperties
來自動裝配這些帳戶信息。下面咱們就以騰訊雲和阿里雲兩家供應商爲例;springboot
@ConfigurationProperties(prefix = "sms") @Data public class SmsProperties { private SmsMessage aliyun = new SmsMessage(); private SmsMessage tencent = new SmsMessage(); @Data public static class SmsMessage{ /** * 用戶名 */ private String userName; /** * 密碼 */ private String passWord; /** * 祕鑰 */ private String sign; /** * */ private String url; @Override public String toString() { return "SmsMessage{" + "userName='" + userName + '\'' + ", passWord='" + passWord + '\'' + ", sign='" + sign + '\'' + ", url='" + url + '\'' + '}'; } } }
若是須要在其餘項目中使用發送短信功能的話,咱們只須要在配置文件(application.yml
)中配置SmsProperties
的屬性信息就能夠了。 好比:mybatis
sms: aliyun: pass-word: 12345 user-name: java金融 sign: 阿里雲 url: http://aliyun.com/send tencent: pass-word: 6666 user-name: java金融 sign: 騰訊雲 url: http://tencent.com/send
還記的@ConfigurationProperties
註解裏面是否是有個prefix
屬性,咱們配置的這個屬性是sms
,配置這個的主要一個做用的話是主要用來區別各個組件的參數。這裏有個小知識點須要注意下當咱們在配置文件輸入sms
咱們的idea
會提示這個sms
有哪些屬性能夠配置,以及每一個屬性的註釋都有標記,建議的話註釋仍是寫英文,這樣會顯得你比較專業。
這個提示的話,是須要引入下面這個jar
的。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
引入這個jar
以後,咱們編譯以後就會在META-INF
文件夾下面生成一個spring-configuration-metadata.json
的文件。
咱們能夠看到這個文件其實 是根據SmsProperties類的成員屬性來生成的。
@EnableConfigurationProperties(value = SmsProperties.class) @Configuration public class SmsAutoConfiguration { /** * 阿里雲發送短信的實現類 * @param smsProperties * @return */ @Bean public AliyunSmsSenderImpl aliYunSmsSender(SmsProperties smsProperties){ return new AliyunSmsSenderImpl(smsProperties.getAliyun()); } /** * 騰訊雲發送短信的實現類 * @param smsProperties * @return */ @Bean public TencentSmsSenderImpl tencentSmsSender(SmsProperties smsProperties){ return new TencentSmsSenderImpl(smsProperties.getTencent()); } }
編寫咱們的發送短信實現類:
public class AliyunSmsSenderImpl implements SmsSender { private SmsMessage smsMessage; public AliyunSmsSenderImpl(SmsMessage smsProperties) { this.smsMessage = smsProperties; } @Override public boolean send(String message) { System.out.println(smsMessage.toString()+"開始發送短信==》短信內容:"+message); return true; } }
starter
集成應用有兩種方式:
SpringBoot
的SPI
的機制來去加載咱們的starter。咱們須要在META-INF
下新建一個spring.factories
文件key
爲org.springframework.boot.autoconfigure.EnableAutoConfiguration, value
是咱們的SmsAutoConfiguration
全限定名(記得去除先後的空格,不然會不生效)。starter
組件集成到咱們的Spring Boot
應用時須要主動聲明啓用該starter
才生效,經過自定義一個@Enable
註解而後在把自動配置類經過Import
註解引入進來。@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({SmsAutoConfiguration.class}) public @interface EnableSms { }
使用的時候須要在啓動類上面開啓這個註解。
5.打包,部署到倉庫
若是是本地的話,直接經過mvn install
命令就能夠了。
若是須要部署到公司的倉庫話,這個就不說了。
6. 新建一個新的SpringBoot
項目引入咱們剛寫的starter
<dependency> <groupId>com.workit.sms</groupId> <artifactId>sms-spring-boot-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
在項目配置文件配上短信帳號信息
測試代碼
@SpringBootApplication @EnableSms public class AutoconfigApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(AutoconfigApplication.class, args); AliyunSmsSenderImpl aliyunSmsSender = applicationContext.getBean(AliyunSmsSenderImpl.class); aliyunSmsSender.send("用阿里雲發送短信"); TencentSmsSenderImpl tencentSmsSender = applicationContext.getBean(TencentSmsSenderImpl.class); tencentSmsSender.send("用騰訊雲發送短信"); }
運行結果:
SmsMessage{userName='java金融', passWord='12345', sign='阿里雲', url='http://aliyun.com/send'}開始發送短信==》短信內容:用阿里雲發送短信 SmsMessage{userName='java金融', passWord='6666', sign='騰訊雲', url='http://tencent.com/send'}開始發送短信==》短信內容:用騰訊雲發送短信
至此的話咱們自定義的一個starter
就已經完成了,這個starter
只是一個演示的demo
,代碼有點粗糙,項目結構也有點問題。重點看下這個實現原理就好。趕忙動動小手去實現一個本身的starter
吧。
SpringBoot starter
的出現,讓咱們項目中集成其餘組件變得簡單。它把簡單給了別人,把複雜留給了本身。「犧牲小我,成就大我」的思想仍是值得學習的。平時咱們工做中,好比要開發一個組件、或者一個工具類,也應該儘量的讓使用方能夠作到無腦使用,不要搞的太複雜,又能讓使用者能夠靈活擴展。