javascript
自定义依赖注解无效_最详细的自定义Spring Boot Starter开发教程
1.前言
隨著Spring的日漸臃腫,為了簡(jiǎn)化配置、開(kāi)箱即用、快速集成,Spring Boot 橫空出世。目前已經(jīng)成為 Java 目前最火熱的框架了。平常我們用Spring Boot開(kāi)發(fā)web應(yīng)用。Spring mvc 默認(rèn)使用tomcat servlet容器, 因?yàn)镾pring mvc組件集成了spring-boot-starter-tomcat 。但是現(xiàn)在undertow servlet容器的性能非常好。我們可以通過(guò)以下方式先排除tomcat:
然后直接替換為undertow:
代碼無(wú)需更改。這就是組件化后的好處:1.可插拔。2.可定制。3.按需集成。為什么能夠做到快速適配?我們?cè)囅胍粋€(gè)這樣一個(gè)場(chǎng)景:假如你的汽車(chē)輪子上有個(gè)螺絲壞了,你要買(mǎi)一個(gè)螺絲去自己裝。你去店里只要報(bào)上你汽車(chē)的品牌和位置老板就能準(zhǔn)確地知道你要用哪種螺絲。這就是標(biāo)準(zhǔn)已經(jīng)制定好的好處。如果沒(méi)有標(biāo)準(zhǔn),你很容易買(mǎi)到不配套的螺絲,你要不停的試錯(cuò)。這顯然不是你想要的。如果把這種標(biāo)準(zhǔn)潛移默化,那么我們?cè)跍贤ㄉ暇透涌旖莘奖恪S袝r(shí)候你女朋友一個(gè)眼神你就知道她想要干什么。所以Spring Boot 有一個(gè)“約定大于配置”的規(guī)則,讓程序組件之間來(lái)減少配置,降低復(fù)雜性。因此你在開(kāi)發(fā)一個(gè)自定義的Spring Boot Starter的時(shí)候也最好考慮你的starter如何達(dá)到以上的便利性。
2. Spring Boot的一些約定
一個(gè)組件的設(shè)計(jì)一定要有標(biāo)準(zhǔn)和規(guī)則。Spring Boot Starter也不例外。我們來(lái)看看一些常規(guī)的做法。
2.1 命名風(fēng)格
如果你快有孩子了,出生前你比較急的一定是起個(gè)名字。姓名標(biāo)識(shí)著你和你愛(ài)人的血統(tǒng),一定不會(huì)起隔壁老王的姓氏,肯定會(huì)招來(lái)異樣的眼光。在maven中,groupId代表著姓氏,artifactId代表著名字。Spring Boot也是有一個(gè)命名的建議的。groupId不要用官方的org.springframework.boot
而要用你自己獨(dú)特的。對(duì)于artifactId的命名,Spring Boot官方建議非官方的Starter命名格式遵循 xxxx-spring-boot-starter ,例如 mybatis-spring-boot-starter 。官方starter會(huì)遵循spring-boot-starter-xxxx ,例如上面提到的spring-boot-starter-undertow 。很多開(kāi)源starter作者會(huì)忽略這種約定,顯得不夠“專(zhuān)業(yè)“。
3. 自定義一個(gè)Starter
接下來(lái)我們構(gòu)建一個(gè)自定義的第三方短信starter,命名為sms-spring-boot-starter 。有一些細(xì)節(jié)問(wèn)題需要邊寫(xiě)邊來(lái)介紹。下面是一個(gè)省略了samples和test模塊模版:
依據(jù)上面我們建立如下項(xiàng)目:
3.1 sms-spring-boot
sms-spring-boot構(gòu)建一個(gè)項(xiàng)目重要的就是依賴(lài)管理。所以引入BOM是必要的。主要管理該starter的所有模塊module,以及starter的所有依賴(lài)甚至sms-spring-boot-autoconfigure都由sms-spring-boot管理。
3.2 autoconfigure
該模塊主要用來(lái)定義配置參數(shù)、以及自動(dòng)配置對(duì)外暴露的功能(一般是抽象的接口Spring Bean)。
3.2.1 Properties配置
一般配置參數(shù)都是在Spring Boot 的application.yml中。我們會(huì)定義一個(gè)前綴標(biāo)識(shí)來(lái)作為名稱(chēng)空間隔離各個(gè)組件的參數(shù)。對(duì)應(yīng)的組件會(huì)定義一個(gè)XXXXProperties 來(lái)自動(dòng)裝配這些參數(shù)。自動(dòng)裝配的機(jī)制基于@ConfigurationProperties注解,請(qǐng)注意一定要顯式聲明你配置的前綴標(biāo)識(shí)(prefix)。我們的sms-spring-boot會(huì)作如下配置:
以上以阿里云的短信功能為例作配置,在將來(lái)使用時(shí)只需要在application.yml中加入上面對(duì)應(yīng)SmsProperties的配置:
如果你集成了Spring Boot 校驗(yàn)庫(kù) 你也可以對(duì)SmsProperties進(jìn)行校驗(yàn)。在配置application.yml時(shí)細(xì)心的java開(kāi)發(fā)者會(huì)發(fā)現(xiàn)參數(shù)配置都有像下面一樣的參數(shù)描述:
就像java中的注釋一樣方便我們理解該配置的作用,其實(shí)這個(gè)就是java注釋生成的。你需要依賴(lài)
然后就該依賴(lài)會(huì)對(duì)SmsProperties 成員屬性的注釋進(jìn)行提取生成一個(gè)spring-configuration-metadata.json文件,這就是配置描述的元數(shù)據(jù)文件。Spring Boot官方也對(duì)注釋進(jìn)行了一些規(guī)則約束:
- 不要以“The”或“A”開(kāi)頭描述。
- 對(duì)于boolean類(lèi)型,請(qǐng)使用“Whether" 或“Enable”開(kāi)始描述。
- 對(duì)于基于集合的類(lèi)型,請(qǐng)使用“Comma-separated list”
- 如果默認(rèn)時(shí)間單位不等同于毫秒,則使用java.time.Duration而不是long描述默認(rèn)單位,例如“如果未指定持續(xù)時(shí)間后綴,則將使用秒”。
- 除非必須在運(yùn)行時(shí)確定,否則不要在描述中提供默認(rèn)值。
補(bǔ)充我個(gè)人建議描述盡量使用英文描述。
3.2.2 配置自動(dòng)暴露功能接口
拿到配置后,接下來(lái)就是根據(jù)配置來(lái)初始化我們的功能接口,我們會(huì)抽象一個(gè)短信發(fā)送接口SmsSender,根據(jù)短信提供方的SDK來(lái)進(jìn)行功能設(shè)計(jì)。請(qǐng)注意autoconfigure模塊的依賴(lài)幾乎都是不可傳遞的。也就是依賴(lài)坐標(biāo)配置optional為true 。功能接口實(shí)現(xiàn)完后我們會(huì)編寫(xiě)一個(gè)自動(dòng)配置類(lèi) SmsAutoConfiguration 。除了@Configuration注解外,@ConfigurationProperties會(huì)幫助我們將我們的配置類(lèi)
SmsProperties加載進(jìn)來(lái)。然后將我們需要暴露的功能接口聲明為Spring Bean 暴露給Spring Boot應(yīng)用 。
有時(shí)候我們還可以通過(guò)一些條件來(lái)控制SmsAutoConfiguration或者SmsSender ,比如根據(jù)某個(gè)條件是否加載或加載不同的
SmsSender。有時(shí)間你可以看看redis-starter就能很明顯感覺(jué)到,它會(huì)根據(jù)luttuce、redisson、jedis 的變化實(shí)例化不同的客戶(hù)端鏈接。實(shí)現(xiàn)方式是使用了@Conditional系列注解,有時(shí)間可以學(xué)習(xí)一下該系列的注解。好了我們的SmsAutoConfiguration聲明如下:
3.2.3 主動(dòng)生效和被動(dòng)生效
starter集成入應(yīng)用有兩種方式。我們從應(yīng)用視角來(lái)看有兩種:
- 一種是主動(dòng)生效,在starter組件集成入Spring Boot應(yīng)用時(shí)需要你主動(dòng)聲明啟用該starter才生效,即使你配置完全。這里會(huì)用到@Import注解,將該注解標(biāo)記到你自定義的@Enable注解上:
我們將該注解標(biāo)記入Spring Boot應(yīng)用就可以使用短信功能了。
- 另一種被動(dòng)生效,在starter組件集成入Spring Boot應(yīng)用時(shí)就已經(jīng)被應(yīng)用捕捉到。這里會(huì)用到類(lèi)似java的SPI機(jī)制。在autoconfigure資源包下新建META-INF/spring.factories寫(xiě)入SmsAutoConfiguration全限定名。
多個(gè)配置類(lèi)逗號(hào)隔開(kāi),換行使用反斜杠。
3.3 sms-spring-boot-starter
該模塊是一個(gè)空jar。它唯一目的是提供必要的依賴(lài)項(xiàng)來(lái)使用starter。你可以認(rèn)為它就是集成該starter功能的唯一入口。不要對(duì)添加啟動(dòng)器的項(xiàng)目做出假設(shè)。如果您自動(dòng)配置的依賴(lài)庫(kù)通常需要其他啟動(dòng)器,請(qǐng)同時(shí)提及它們。如果可選依賴(lài)項(xiàng)的數(shù)量很高,則提供一組適當(dāng)?shù)哪J(rèn)依賴(lài)項(xiàng)可能很難,因?yàn)槟鷳?yīng)該避免包含對(duì)典型庫(kù)的使用不必要的依賴(lài)項(xiàng)。換句話(huà)說(shuō),您不應(yīng)該包含可選的依賴(lài)項(xiàng)。
無(wú)論哪種方式,您的starter必須直接或間接引用核心Spring Boot啟動(dòng)器(spring-boot-starter)(如果您的啟動(dòng)器依賴(lài)于另一個(gè)啟動(dòng)器,則無(wú)需添加它)。如果只使用自定義啟動(dòng)器創(chuàng)建項(xiàng)目,則Spring Boot的核心功能將通過(guò)核心啟動(dòng)器的存在來(lái)實(shí)現(xiàn)。
我們的sms-spring-boot-starter僅僅是以下的pom:
到此為止,我們的整個(gè)短信Starter就開(kāi)發(fā)完成了。
4. 總結(jié)
自定義starter對(duì)于我們項(xiàng)目組件化、模塊化是有很大幫助的。同時(shí)也是Spring Boot一大特色。相信通過(guò)小胖的介紹你已經(jīng)蠢蠢欲試了,那么就趕緊開(kāi)始寫(xiě)一個(gè)吧。如果覺(jué)得對(duì)你有用可以點(diǎn)個(gè)贊關(guān)注一下。
原文:https://mp.weixin.qq.com/s/ezz1zQ6O4qV4pwqz1UjdTg作者:碼農(nóng)小胖哥
來(lái)源:微信公眾號(hào)
總結(jié)
以上是生活随笔為你收集整理的自定义依赖注解无效_最详细的自定义Spring Boot Starter开发教程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 小科普 | 大果粒?如何让Windows
- 下一篇: freertos源码详解与应用开发 pd