javascript
Spring Boot 2中的功能切换
無論您是否喜歡,軟件開發(fā)都是一項(xiàng)協(xié)作活動(dòng)。 整合工作一直被妖魔化,并被視為必不可少的邪惡。 有幾種方法可以解決有效集成的挑戰(zhàn)。 功能切換開關(guān)屬于該組。 在本文中,您將在實(shí)踐中看到如何在Spring Boot應(yīng)用程序中使用功能切換(也稱為功能標(biāo)志)。
1.什么是功能切換?
簡(jiǎn)而言之, 功能切換是允許根據(jù)其當(dāng)前值在應(yīng)用程序中執(zhí)行替代路徑的變量。 通過保持不同的執(zhí)行方案,您可以在不更改代碼的情況下修改應(yīng)用程序的行為。
根據(jù)您的需求,可以在啟動(dòng)應(yīng)用程序之前設(shè)置切換開關(guān)的值,也可以在運(yùn)行時(shí)對(duì)其進(jìn)行調(diào)整。 在后一種情況下,值的更改可以保留或僅影響應(yīng)用程序的當(dāng)前執(zhí)行。
通常,您會(huì)讀到有關(guān)功能標(biāo)志的信息, 以作為功能源代碼分支的替代方法 ,但是,實(shí)際上,兩種技術(shù)可以一起使用。 例如,您可以使用功能分支在應(yīng)用程序中開發(fā)新的用戶故事,同時(shí)可以使用功能切換來控制對(duì)不同環(huán)境(例如,具有不同要求的客戶端)上功能的訪問。
盡管有許多用途,功能切換也有其缺點(diǎn)。 最大的問題是復(fù)雜性 。 如果沒有適當(dāng)?shù)牟呗?#xff0c;他們可能會(huì)Swift失控,成為維護(hù)的噩夢(mèng)。 幸運(yùn)的是,如果您遵循幾種良好的做法并圍繞features來組織應(yīng)用程序 ,則使用Feature標(biāo)志應(yīng)該更加簡(jiǎn)單。
2.使用功能切換選擇豆
在Spring Boot應(yīng)用程序中使用功能切換的最常見情況是基于功能切換的當(dāng)前值激活某些接口的不同實(shí)現(xiàn)。 我們來看一個(gè)示例來說明所描述的情況。
2.1依賴抽象
假設(shè)您有一個(gè)Web端點(diǎn),該端點(diǎn)返回從數(shù)據(jù)庫(kù)存儲(chǔ)庫(kù)中獲取的產(chǎn)品列表。 您的目標(biāo)是創(chuàng)建一個(gè)功能切換,該功能切換允許將存儲(chǔ)庫(kù)實(shí)現(xiàn)切換為使用Web服務(wù)作為數(shù)據(jù)源的實(shí)現(xiàn)。
如果要允許要素切換的類直接在其他類中使用,則您要做的第一件事是使用接口抽象依賴關(guān)系。
下面的代碼片段提供了一個(gè)示例Product REST端點(diǎn),該端點(diǎn)依賴于ProductRepository接口。
@RestController @RequestMapping("/products") class ProductController {private final ProductRepository productRepository;ProductController(ProductRepository productRepository) {this.productRepository = productRepository;}@GetMappingCollection<Product> getAll() {return productRepository.findAll();}}目前,我們只有一個(gè)接口實(shí)現(xiàn)。 不久,我們將添加另一個(gè),您將通過功能切換激活它。
@Repository class DbProductRepository implements ProductRepository {//... }2.2 application.properties中的功能切換
由于application.properties文件用于配置Spring Boot應(yīng)用程序,因此是放置功能切換標(biāo)志的好地方。
feature.toggles.productsFromWebService=true在提交代碼之前,將標(biāo)志設(shè)置為false。 這樣,默認(rèn)情況下,您的隊(duì)友將禁用新功能。 如果有人要激活該功能,則他們可以在本地開發(fā)環(huán)境中將標(biāo)志值更改為true。
2.3有條件的Bean創(chuàng)建
下一步是創(chuàng)建要通過功能切換激活的接口的替代實(shí)現(xiàn)。 為了根據(jù)創(chuàng)建的屬性的值實(shí)例化bean,可以使用Spring Boot注釋@ConditionalOnProperty 。 設(shè)置切換屬性的名稱和應(yīng)激活它的值。 該值應(yīng)與放在application.properties文件中的值相同。
@Repository @ConditionalOnProperty(name = "feature.toggles.productsFromWebService",havingValue = "true" ) class WebServiceProductRepository implements ProductRepository {//... }在啟動(dòng)應(yīng)用程序之前,必須禁用數(shù)據(jù)庫(kù)存儲(chǔ)庫(kù),否則,您將獲得有關(guān)接口的多個(gè)活動(dòng)實(shí)現(xiàn)的異常。 返回第一個(gè)實(shí)現(xiàn)并應(yīng)用以下更改:
@Repository @ConditionalOnProperty(name = "feature.toggles.productsFromWebService",havingValue = "false",matchIfMissing = true ) class DbProductRepository implements ProductRepository {我們使用與以前相同的功能切換名稱,只是其值已更改。 設(shè)置matchIfMissing屬性是可選的。 這樣,如果您從application.properties文件中刪除功能切換,即使缺少該值,也將創(chuàng)建該bean。
3.如何通過功能切換禁用控制器
您可以應(yīng)用相同的策略有條件地激活整個(gè)Spring Web控制器。 您不需要?jiǎng)?chuàng)建其他接口,因?yàn)槟幌胪ㄟ^功能切換控制一個(gè)實(shí)現(xiàn)。
@RestController @RequestMapping("/coupons") @ConditionalOnProperty(name = "feature.toggles.coupons", havingValue = "true") class CouponController {//... }application.properties應(yīng)該包含以下行。
feature.toggles.coupons=true當(dāng)您不將值設(shè)置為true時(shí),Spring不會(huì)實(shí)例化控制器。 客戶端將僅收到404 HTTP狀態(tài)代碼。
不幸的是, @ ConditionalOnProperty批注不能在單個(gè)@RequestMapping方法上使用。 解決方法是,可以將所需的映射移動(dòng)到單獨(dú)的控制器Bean。 或者,可以簡(jiǎn)單地插入功能切換的值并在映射方法的主體中創(chuàng)建if語(yǔ)句。 但是,您應(yīng)謹(jǐn)慎使用此解決方案。 如果您有興趣,為什么在下一段中找到答案。
private final boolean couponsToggled;CouponController(@Value("${feature.toggles.coupons}") boolean couponsToggled) {this.couponsToggled = couponsToggled; }@GetMapping List<String> listCouponNames() {if (!couponsToggled) {throw new NotSupportedException();}//... }4.多功能切換管理
正如您可以閱讀Martin Fowler的bliki上的功能切換一樣 , 功能標(biāo)志傾向于在整個(gè)代碼庫(kù)中擴(kuò)展,并且很快就會(huì)變得難以管理 。 即使您的應(yīng)用程序中只有幾個(gè)功能切換,最好還是從使用標(biāo)記的決策點(diǎn)抽象出標(biāo)記的存儲(chǔ)。
4.1避免特征標(biāo)記耦合
上一段中的最后一個(gè)代碼示例使用直接從application.properties文件注入的標(biāo)志值,因此不會(huì)抽象存儲(chǔ)。 如果要在應(yīng)用程序的不同部分中使用相同的標(biāo)志,則必須重復(fù)注入。
相反,您可以做的是將所有功能切換值放在一個(gè)類中,這將作為單個(gè)true來源 。 使用單獨(dú)的類可為您提供更大的靈活性。 例如,您可以用數(shù)據(jù)庫(kù)替換標(biāo)志的存儲(chǔ),或者實(shí)現(xiàn)一種允許在運(yùn)行時(shí)切換標(biāo)志的機(jī)制。
4.2在Spring Boot中提取功能切換決策
一旦具有用于功能切換的單獨(dú)的bean,就可以使用@ConfigurationProperties批注輕松地從application.properties文件中注入所有標(biāo)志。 在這里,您可以看到一個(gè)示例實(shí)現(xiàn):
@Component @Component @ConfigurationProperties("feature") public class FeatureDecisions {private Map<String, Boolean> toggles = new HashMap<>();public Map<String, Boolean> getToggles() {return toggles;}public boolean couponEnabled() {return toggles.getOrDefault("coupons", false);}}上面的類將獲取所有以feature.toggles開頭的屬性,并將它們放入切換圖。 如您所見,有一個(gè)名為couponEnabled()的方法,可用于從決策背后的邏輯中提取功能決策點(diǎn)。
此外,您還需要一個(gè)額外的依賴項(xiàng)才能啟用對(duì)@ConfigurationProperties的處理。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId> </dependency>5.用于功能切換的執(zhí)行器端點(diǎn)
由于您已經(jīng)將所有功能切換都放在一個(gè)位置,因此現(xiàn)在要做的就是使用自定義的Actuator端點(diǎn)公開列表。 以下示例將向您展示如何進(jìn)行。
@Component @Endpoint(id = "feature-toggles") class FeatureToggleInfoEndpoint {private final FeatureDecisions featureDecisions;FeatureToggleInfoEndpoint(FeatureDecisions featureDecisions) {this.featureDecisions = featureDecisions;}@ReadOperationpublic Map<String, Boolean> featureToggles() {return featureDecisions.getToggles();}}如果您使用默認(rèn)的Spring Boot 2 Actuator設(shè)置,則不會(huì)通過HTTP公開端點(diǎn) 。 為了在瀏覽器中對(duì)其進(jìn)行測(cè)試,您必須通過將其標(biāo)識(shí)符添加到application.properties文件中的Web include過濾器來啟用Actuator端點(diǎn)。
management.endpoints.web.exposure.include=health,info,feature-toggles運(yùn)行應(yīng)用程序后,請(qǐng)轉(zhuǎn)到http:// localhost:8080 / actuator / feature-toggles查看端點(diǎn)返回的結(jié)果:
根據(jù)您的需求,您還可以在創(chuàng)建的端點(diǎn)上使用@WriteOperation實(shí)現(xiàn)在運(yùn)行時(shí)切換功能切換的可能性。 本示例僅涵蓋輸出部分。
結(jié)論
在本文中,您可以了解Spring Boot應(yīng)用程序中功能切換的實(shí)際示例。 我們從一個(gè)非常基本的示例開始,該示例涵蓋了框架的所有需求。 之后,我們編寫一些自定義代碼來完成更多的自定義功能切換要求。 我們完成了有用的Actuator端點(diǎn),以顯示應(yīng)用程序中所有功能標(biāo)志的狀態(tài)。
您可以在Github存儲(chǔ)庫(kù)中找到工作示例應(yīng)用程序 。 如果您喜歡該帖子并認(rèn)為它有用,請(qǐng)與您的關(guān)注者分享。 我也期待您在本文下面的問題和評(píng)論。
翻譯自: https://www.javacodegeeks.com/2018/03/feature-toggle-in-spring-boot-2.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Spring Boot 2中的功能切换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不只有“鸡血版”骁龙8 Gen3!三星G
- 下一篇: gradle idea java ssm