Spring-Smart-DI 動態(tài)切換實現(xiàn)類的步驟
前言: 在系統(tǒng)開發(fā)的實際場景中,我們常常會碰到這樣一類需求:同一個功能需要對接多個服務(wù)提供商。這么做主要基于兩個重要原因。
其一,為了規(guī)避某個服務(wù)商的服務(wù)出現(xiàn)不可用的風(fēng)險,以便在出現(xiàn)問題時能夠迅速切換到其他服務(wù)商,確保系統(tǒng)的穩(wěn)定性和業(yè)務(wù)的連續(xù)性;
其二,不同服務(wù)商的收費標(biāo)準(zhǔn)存在差異,從成本控制的角度出發(fā),需要根據(jù)實際情況進(jìn)行靈活切換。
傳統(tǒng)的快速切換邏輯實現(xiàn)方法是,先為每個服務(wù)商編寫對應(yīng)的實現(xiàn)類,然后在配置點(這個配置點可以是數(shù)據(jù)庫,也可以是像 Nacos 這樣的配置中心)配置當(dāng)前正在使用的服務(wù)商。在每次執(zhí)行相關(guān)業(yè)務(wù)邏輯時,都要從配置點獲取當(dāng)前使用的服務(wù)商信息,再去執(zhí)行該服務(wù)商對應(yīng)的業(yè)務(wù)邏輯。
以系統(tǒng)接入多個短信服務(wù)商為例,用戶可以根據(jù)自身需求動態(tài)地在不同服務(wù)商之間進(jìn)行切換。下面我們詳細(xì)看看如果手動實現(xiàn)這個功能,具體步驟是怎樣的。
第一步,在某個配置位置(例如 Nacos 或者數(shù)據(jù)庫)配置當(dāng)前使用的服務(wù)商對應(yīng)的標(biāo)識值。比如,我們設(shè)置 sms.impl = “某騰短信”。
第二步,在代碼中執(zhí)行發(fā)短信操作時,手動獲取 sms.impl 對應(yīng)的服務(wù)商實現(xiàn)類。以下是相應(yīng)的偽代碼示例:
void sendSmsTouser(Req req) { // 1、獲取當(dāng)前使用的服務(wù)商 String name = get("sms.impl"); // 2、獲取對應(yīng)的實現(xiàn)類 SmsService smsService = springContext.getBean(name); // 3、使用 smsService 執(zhí)行具體業(yè)務(wù)邏輯 smsService.sendMsg(req); }
不過,這種實現(xiàn)方式存在明顯的弊端,它比較繁瑣,每次執(zhí)行都需要手動去獲取配置并加載對應(yīng)的實現(xiàn)類。那么,有沒有一種更優(yōu)雅的方式,讓 Spring 的 @Autowired注解在注入時能夠自動根據(jù)配置點的配置去注入對應(yīng)的實現(xiàn)類,并且當(dāng)配置發(fā)生變化時,注入的實現(xiàn)類也能自動更新呢?spring-smart-di 的@AutowiredProxySPI 就是為解決這個問題而精心設(shè)計的。
1. spring-smart-di 簡介
--------------------------------------------------------------------------------------
spring-smart-di 是對 Spring@Autowired 注解的一次創(chuàng)新性擴展,它為用戶提供了自定義 Autowired 注入邏輯的能力。目前,它實現(xiàn)了兩個非常重要的注解:@SmartAutowired 和@AutowiredProxySPI 。在本文中,我們將重點聚焦于如何使用AutowiredProxySPI 來實現(xiàn)動態(tài)切換服務(wù)提供商的功能。
假設(shè)我們的系統(tǒng)對接了多個短信服務(wù)商,下面我們通過一個快速上手的案例,詳細(xì)了解如何使用 AutowiredProxySPI來實現(xiàn)動態(tài)切換。
2、快速開始
2.1 引入依賴
首先,我們需要在項目中引入 spring-smart-di 的依賴。在 Maven 項目的 pom.xml 文件中添加以下依賴代碼:
<dependency> <groupId>io.github.burukeyou</groupId> <artifactId>spring-smart-di-all</artifactId> <version>0.2.0</version> </dependency>
2.2 啟用功能
在 Spring 配置類上標(biāo)記 @EnableSmartDI 注解,以此來啟用 spring-smart-di 的強大功能。
2.3 @EnvironmentProxySPI 注解的使用
@EnvironmentProxySPl注解代表著一個配置點,其主要作用是配置如何獲取具體實現(xiàn)類的邏輯。
假設(shè)我們的系統(tǒng)中有兩個短信服務(wù)商,需要實現(xiàn)動態(tài)切換。我們需要在接口上配置 @EnvironmentProxySPl注解,表示從環(huán)境變量配置點中獲取當(dāng)前使用的服務(wù)商。這里我們將配置信息存儲在屬性${sms.impl} 中。
@EnvironmentProxySPI("${sms.impl}") publicinterface SmsService { } // 給實現(xiàn)類定義別名 @BeanAliasName("某騰短信服務(wù)") @Component publicclass ASmsService implements SmsService { } @BeanAliasName("某移短信服務(wù)") @Component publicclass BSmsService implements SmsService { }
2.4 配置當(dāng)前使用的服務(wù)商
我們可以在配置文件中配置當(dāng)前使用的服務(wù)商。配置的值可以是 @BeanAliasName注解指定的值,也可以是@Component 注解指定的值,還可以是具體的全路徑類名。
sms: impl: 某移短信服務(wù)
2.5 @AutowiredProxySPI 注入使用
接下來,我們只需要像使用 @Autowired 注解一樣使用 @AutowiredProxySPI 注解即可。
// 依賴注入 @AutowiredProxySPI private SmsService smsService;
通過以上步驟,我們就成功完成了動態(tài)切換服務(wù)提供商的需求。只要我們改變配置屬性${sms.impl} 的值,系統(tǒng)就會實時生效,而無需重啟服務(wù)。這是因為@AutowiredProxySPI 注入的是一個代理對象,每次執(zhí)行時會先實時獲取當(dāng)前使用的實現(xiàn)類,然后再執(zhí)行調(diào)用操作。并且,在使用上與直接使用 @Autowired 注解基本沒有區(qū)別。
2.6 定義不同的配置點
@EnvironmentProxySPI 注解主要用于配置環(huán)境變量相關(guān)的配置點。如果我們想要自定義配置,例如從數(shù)據(jù)庫中獲取配置信息,可以實現(xiàn)自己的 ProxySPI 注解。下面是一個自定義 DBProxySPI 注解的示例,我們需要標(biāo)記上 @ProxySPI 注解,并指定具體的配置獲取邏輯實現(xiàn)類 AnnotationProxyFactory 。
@Inherited @Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @ProxySPI(DbProxyFactory.class) // 指定配置獲取邏輯 public @interface DBProxySPI { String value(); } @Component publicclass DbProxyFactory implements AnnotationProxyFactory<DBProxySPI> { @Autowired private SysConfigMapper sysConfigDao; @Override public Object getProxy(Class<?> targetClass, DBProxySPI spi) { // 根據(jù)注解從數(shù)據(jù)庫獲取要注入的實現(xiàn)類 String configName = sysConfigDao.getConfig(spi.value()); return springContext.getBean(configName); } } @DBProxySPI("${sms.impl}") publicinterface SmsService { }
通過以上的步驟,我們就可以靈活地實現(xiàn)動態(tài)切換服務(wù)提供商的功能,并且可以根據(jù)不同的需求自定義配置獲取邏輯。 spring-smart-di 為我們提供了一種簡潔、高效的方式來處理這種動態(tài)切換的場景,讓我們的代碼更加靈活和易于維護(hù)。
到此這篇關(guān)于Spring-Smart-DI 動態(tài)切換實現(xiàn)類的文章就介紹到這了,更多相關(guān)Spring-Smart-DI 動態(tài)切換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot連接redis并動態(tài)切換database的實現(xiàn)方法
- Springboot動態(tài)切換數(shù)據(jù)源的具體實現(xiàn)與原理分析
- 詳細(xì)聊聊SpringBoot中動態(tài)切換數(shù)據(jù)源的方法
- spring-data-redis 動態(tài)切換數(shù)據(jù)源的方法
- spring實現(xiàn)動態(tài)切換、添加數(shù)據(jù)源及源碼分析
- Spring+Mybatis動態(tài)切換數(shù)據(jù)源的方法
- Spring整合多數(shù)據(jù)源實現(xiàn)動態(tài)切換的實例講解
- Spring + Mybatis 項目實現(xiàn)動態(tài)切換數(shù)據(jù)源實例詳解
相關(guān)文章
java 直接調(diào)用python腳本,并傳遞參數(shù)代碼實例
這篇文章主要介紹了java調(diào)用python腳本傳遞參數(shù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Java創(chuàng)建型設(shè)計模式之抽象工廠模式(Abstract?Factory)
當(dāng)系統(tǒng)所提供的工廠所需生產(chǎn)的具體產(chǎn)品并不是一個簡單的對象,而是多個位于不同產(chǎn)品等級結(jié)構(gòu)中屬于不同類型的具體產(chǎn)品時需要使用抽象工廠模式,抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形態(tài)2022-09-09MySQL如何設(shè)置自動增長序列SEQUENCE的方法
本文主要介紹了MySQL如何設(shè)置自動增長序列SEQUENCE的方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12Spring mvc JSON數(shù)據(jù)交換格式原理解析
這篇文章主要介紹了Spring mvc JSON數(shù)據(jù)交換格式原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03Java按照List內(nèi)存儲的對象的某個字段進(jìn)行排序的實例
下面小編就為大家?guī)硪黄狫ava按照List內(nèi)存儲的對象的某個字段進(jìn)行排序的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12SpringBatch數(shù)據(jù)讀取的實現(xiàn)(ItemReader與自定義讀取邏輯)
本文主要介紹了SpringBatch數(shù)據(jù)讀取的實現(xiàn), 文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04Spring mvc是如何實現(xiàn)與數(shù)據(jù)庫的前后端的連接操作的?
今天給大家?guī)淼氖顷P(guān)于Spring mvc的相關(guān)知識,文章圍繞著Spring mvc是如何實現(xiàn)與數(shù)據(jù)庫的前后端的連接操作的展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06Flowable?設(shè)置任務(wù)處理人的四種方式詳解
這篇文章主要為大家介紹了Flowable?設(shè)置任務(wù)處理人的四種方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10SpringBoot混合使用StringRedisTemplate和RedisTemplate的坑及解決
這篇文章主要介紹了SpringBoot混合使用StringRedisTemplate和RedisTemplate的坑及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12