springboot接口多實現(xiàn)類選擇性注入解決方案
一、問題的描述
在實際的系統(tǒng)應(yīng)用開發(fā)中我經(jīng)常會遇到這樣的一類需求,相信大家在工作中也會經(jīng)常遇到:
同一個系統(tǒng)在多個省份部署。
一個業(yè)務(wù)在北京是一種實現(xiàn)方式,是基于北京用戶的需求。
同樣的業(yè)務(wù)在上海是另外一種實現(xiàn)方式,與北京的實現(xiàn)方式大同小異
遇到這樣的需求,我們通常會定義一個業(yè)務(wù)實現(xiàn)的接口,比如:
public interface IDemoService {
public void doSomething();
}
在北京環(huán)境下這樣實現(xiàn),比如:
@Component
public class DemoServiceBeijing implements IDemoService {
@Override
public void doSomething() {System.out.println("北京的業(yè)務(wù)實現(xiàn)");}
}
在上海環(huán)境下這樣實現(xiàn),比如:
@Component
public class DemoServiceShanghai implements IDemoService {
@Override
public void doSomething() {System.out.println("上海的業(yè)務(wù)實現(xiàn)");}
}
然后我們寫一個模擬業(yè)務(wù)測試用例
@SpringBootTest
class DemoApplicationTests {
//這里注入的demoService是DemoServiceShanghai,還是DemoServiceBeijing?
@Resource
IDemoService demoService;
@Test
void testDemoService() {
demoService.doSomething();
}
}
當(dāng)我們執(zhí)行這個測試用例的時候一定會報錯,因為Spring發(fā)現(xiàn)了兩個IDemoService的實現(xiàn)類。它不知道去實例化哪一個實現(xiàn)類,來作為IDemoService的實際業(yè)務(wù)處理bean。當(dāng)然我們期望的狀態(tài)是:
在北京部署系統(tǒng)的時候,使用DemoServiceBeijing作為IDemoService的實現(xiàn)類完成依賴注入
在上海部署系統(tǒng)的時候,使用DemoServiceShanghai作為IDemoService的實現(xiàn)類完成依賴注入
二、相對低級解決方案
面對上面的需求,先說幾個相對低級的解決方案,這幾個方案雖然可以實現(xiàn)我們期望的狀態(tài),但是對運(yùn)維不夠友好。
2.1. 方案一:使用@Primary注解
假如在北京部署系統(tǒng)的時候,在DemoServiceBeijing的類上面加上@Primary,該注解的作用就是強(qiáng)迫從多個實現(xiàn)類里面選一個實現(xiàn)類,如果Spring不知道選哪一個,我們告訴它一個默認(rèn)的。
2.2. 方案二:使用@Resource注解
因為@Resource注解默認(rèn)使用名稱進(jìn)行依賴注入,所以變量名明確叫做demoServiceBeijing(首字母小寫),使用的就是DemoServiceBeijing實現(xiàn)類。
@Resource IDemoService demoServiceBeijing; //這里的變量名稱指定了bean名稱 //IDemoService demoService; 被替換掉
或者
@Resource(name = "demoServiceBeijing") //使用resource注解明確指定名稱 IDemoService demoService;
2.3.方案三:使用@Qualifier注解
與上文同樣的道理,使用@Qualifier注解,指定bean的名稱進(jìn)行依賴注入
@Qualifier("demoServiceBeijing") //使用Qualifier注解明確指定名稱
@Resource
IDemoService demoService;
上面所提到的三個方案雖然都可以解決:在不同的部署環(huán)境下使用不同的接口實現(xiàn)類完成依賴注入的問題。但是這樣不好,因為一旦我們要把部署環(huán)境從beijing(北京)換成shanghai(上海),就需要把上面的注解的位置或者內(nèi)容全都修改一遍(所有的實現(xiàn)類代碼都要修改)。
三、相對高級的解決方案
我們提出進(jìn)一步的期望:就是只修改一個配置就能完成部署環(huán)境切換的操作。比如:
deploy: province: beijing
當(dāng)我們期望把部署環(huán)境從北京切換到上海的時候,只需要將上文配置中的beijing 改成 shanghai ,這該怎么實現(xiàn)呢?
在北京的實現(xiàn)類上面加上ConditionalOnProperty注解,havingValue的值為beijing
@Component
@ConditionalOnProperty(value="deploy.province",havingValue = "beijing")
public class DemoServiceBeijing implements IDemoService {
在上海的實現(xiàn)類上面加上ConditionalOnProperty注解,havingValue的值為shanghai
@Component
@ConditionalOnProperty(value="deploy.province",havingValue = "shanghai")
public class DemoServiceShanghai implements IDemoService {
ConditionalOnProperty注解在這里的作用就是:讀取配置文件發(fā)現(xiàn)deploy.province,并將該配置的值與havingValue匹配,匹配上哪一個就實例化哪一個類作為該接口的實現(xiàn)類bean注入到Spring容器中(當(dāng)然注入過程需要配合@Component注解實現(xiàn))
以上就是springboot接口多實現(xiàn)類選擇性注入解決方案的詳細(xì)內(nèi)容,更多關(guān)于springboot接口多實現(xiàn)類選擇性注入的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Java Fibonacci Search斐波那契搜索算法代碼實現(xiàn)
這篇文章主要介紹了詳解Java Fibonacci Search斐波那契搜索算法代碼實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
idea亂碼修改bin目錄下的idea.exe.vmoptions無效問題
這篇文章主要介紹了idea亂碼修改bin目錄下的idea.exe.vmoptions無效問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
Spring Boot不同版本Redis設(shè)置JedisConnectionFactory詳解
本文章向大家介紹Spring Boot不同版本Redis設(shè)置JedisConnectionFactory,主要內(nèi)容包括1.X 版本、2.X 版本、2.、基本概念、基礎(chǔ)應(yīng)用、原理機(jī)制和需要注意的事項等,并結(jié)合實例形式分析了其使用技巧,希望通過本文能幫助到大家理解應(yīng)用這部分內(nèi)容2023-09-09
解決Springboot中Feignclient調(diào)用時版本問題
這篇文章主要介紹了解決Springboot中Feign?client調(diào)用時版本問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
SpringBoot實現(xiàn)application配置信息加密
在配置文件中,我們有開發(fā)環(huán)境配置和生產(chǎn)環(huán)境配置,而生產(chǎn)環(huán)境的配置信息是需要做好防護(hù)的,避免外泄,所以本文為大家整理了application配置信息加密的方法,需要的可以參考下2023-07-07

