您好,登錄后才能下訂單哦!
小編給大家分享一下spring-boot下滿足多生產(chǎn)環(huán)境中個性化定制功能的案例,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
在項(xiàng)目的開發(fā)中,我們很難做到開發(fā)一套標(biāo)準(zhǔn)的流程來解決所有客戶的需求。比如,我們當(dāng)前的計(jì)量項(xiàng)目,分別運(yùn)行于赤峰市和河北省。雖然兩個區(qū)域處理的業(yè)務(wù)相同,但是對細(xì)節(jié)的實(shí)現(xiàn)要求卻不同。前面也學(xué)習(xí)過計(jì)量檢定軟件,其為了解決各個定制者使用的功能需求,最后采取的方案是:將基礎(chǔ)項(xiàng)目復(fù)制多份,進(jìn)而滿足不同的客戶需求。優(yōu)點(diǎn)當(dāng)然是有的,但比起缺點(diǎn)來,優(yōu)點(diǎn)便不值一提。缺點(diǎn)很明顯,總結(jié)為一句話就是:項(xiàng)目變得難以維護(hù)。所以,當(dāng)前讓我們看到的就是,幾個開發(fā)人員,每天處于解決問題當(dāng)中。本文將給出一種方案,來有效的規(guī)避上述問題。
資源與環(huán)境
示例代碼:https://github.com/mengyunzhi/springBootSampleCode/tree/master/dynamic-autowire
開發(fā)環(huán)境:java1.8 + spring-boot:2.1.3.RELEASE
需求假設(shè)
假設(shè)使用本項(xiàng)目的人員為:中國人、美國人,分別能接受的語言為中文和英文。
項(xiàng)目運(yùn)行后,可以根據(jù)當(dāng)前的訪問人員是國籍來動態(tài)顯示:你好
或hello
有新的需求后,比如:增加德國人并顯示Hallo
。增加功能時,不更改核心代碼。
不使用if else
注意:如果你看完需求假設(shè)后,毫無觸動,請忽略本文以下內(nèi)容
解決方案
解決方案中,我們涉及了兩種設(shè)計(jì)模塊,分別為:策略模式
及工廠模式
。
策略模式:一般用于將具體的算法
進(jìn)行抽象及剝離。此項(xiàng)目中,我們的具體算法是說你好
。
工廠模式:一般用于根據(jù)環(huán)境來動態(tài)的創(chuàng)建BEAN的情況下。引項(xiàng)目中,我們將根據(jù)不同國家的人,來返回不同的說你好
這個算法。
先給出UML圖:
SpeakService
SpeakService
即為我們供其它模塊調(diào)用的說話服務(wù)
,調(diào)用其中的SayHello()
來完成說你好
功能。
package com.mengyunzhi.demo.dynamicautowire; /** * 你好 */ public interface SpeakService { void sayHello(); }
在其實(shí)現(xiàn)類中,我們注入SayHelloFactory
,讓其來返回正確的SayHelloService
,最終調(diào)用sayHello()
來完成目標(biāo)。
package com.mengyunzhi.demo.dynamicautowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * 你好 */ @Service public class SpeakServiceImpl implements SpeakService { private final SayHelloFactory sayHelloFactory; // 說話工廠 @Autowired public SpeakServiceImpl(SayHelloFactory sayHelloFactory) { this.sayHelloFactory = sayHelloFactory; } @Override public void sayHello() { this.sayHelloFactory.getSayHelloService().sayHello(); } }
SayHelloFactory
package com.mengyunzhi.demo.dynamicautowire; /** * 說話工廠 */ public interface SayHelloFactory { void setCountryCode(CountryCode countryCode); SayHelloService getSayHelloService(); }
在此,我們增加一個CountryCode
表示當(dāng)前訪問者的國家。其實(shí)在獲取訪問者國家時,我們也可以調(diào)用其它Bean的其它來實(shí)現(xiàn)。
package com.mengyunzhi.demo.dynamicautowire; /** * 國家代碼 */ public enum CountryCode { CHINA((byte) 0, "中國"), USA((byte) 1, "美國"); private Byte code; private String name; CountryCode(Byte code, String name) { this.code = code; this.name = name; } public Byte getCode() { return code; } public String getName() { return name; } }
使用enum
來控制范圍,避免Factory
在獲取Bean時發(fā)生異常。
package com.mengyunzhi.demo.dynamicautowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 說話工廠 */ @Service public class SayHelloFactoryImpl implements SayHelloFactory { /** * BEAN列表 */ private final Map<Byte, SayHelloService> servicesByCode = new HashMap<>(); /** * 國家代碼 */ private CountryCode countryCode = CountryCode.CHINA; @Override public void setCountryCode(CountryCode countryCode) { this.countryCode = countryCode; } /** * 初始化 * * @param sayHelloServices spring獲取到的所以實(shí)現(xiàn)了SpeakService的BEAN */ @Autowired public void init(List<SayHelloService> sayHelloServices) { for (SayHelloService sayHelloService : sayHelloServices) { this.register(sayHelloService.getCode(), sayHelloService); } } /** * 注冊Bean * * @param code 代碼 * @param sayHelloService BEAN */ private void register(Byte code, SayHelloService sayHelloService) { this.servicesByCode.put(code, sayHelloService); } /** * 獲取BEAN * * @return 對應(yīng)的SayHelloService BEAN */ @Override public SayHelloService getSayHelloService() { return this.servicesByCode.get(this.countryCode.getCode()); } }
增加Map<Byte, SayHelloService> servicesByCode
來存儲對應(yīng)國家的SayHelloService
BEAN。增加getSayHelloService()
來根據(jù)當(dāng)前國家代碼來返回相應(yīng)的Bean。
SayHelloService
package com.mengyunzhi.demo.dynamicautowire; /** * 說話 */ public interface SayHelloService { void sayHello(); Byte getCode(); }
將sayHello()
方法抽離,getCode()
以獲取國家代碼。
中國人你好
package com.mengyunzhi.demo.dynamicautowire; import org.springframework.stereotype.Component; /** * 中國話 */ @Component public class SayHelloServiceChineseImpl implements SayHelloService { @Override public void sayHello() { System.out.println("您好"); } @Override public Byte getCode() { return CountryCode.CHINA.getCode(); } }
美國人Hello
package com.mengyunzhi.demo.dynamicautowire; import org.springframework.stereotype.Component; /** * 美國話 */ @Component public class SayHelloServiceEnglishImpl implements SayHelloService { @Override public void sayHello() { System.out.println("hello"); } @Override public Byte getCode() { return CountryCode.USA.getCode(); } }
測試
package com.mengyunzhi.demo.dynamicautowire; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @SpringBootTest @RunWith(SpringRunner.class) public class SpeakServiceImplTest { @Autowired SpeakService speakService; @Autowired SayHelloFactory sayHelloFactory; @Test public void sayHello() { // 默認(rèn)說你好 speakService.sayHello(); // 將國家設(shè)置為美國,再說你好 sayHelloFactory.setCountryCode(CountryCode.USA); speakService.sayHello(); // 將國家設(shè)置為中國,再說你好 sayHelloFactory.setCountryCode(CountryCode.CHINA); speakService.sayHello(); } }
您好
hello
您好
時序圖
增加德國人
增加德國人SayHelloServiceGermanyImpl
.
在CountryCode
中,增加德國.
package com.mengyunzhi.demo.dynamicautowire; import org.springframework.stereotype.Component; @Component public class SayHelloServiceGermanyImpl implements SayHelloService { @Override public void sayHello() { System.out.println("Hallo"); } @Override public Byte getCode() { return CountryCode.GERMANY.getCode(); } }
package com.mengyunzhi.demo.dynamicautowire; /** * 國家代碼 */ public enum CountryCode { CHINA((byte) 0, "中國"), USA((byte) 1, "美國"), GERMANY((byte) 2, "德國"); private Byte code; private String name; CountryCode(Byte code, String name) { this.code = code; this.name = name; } public Byte getCode() { return code; } public String getName() { return name; } }
單元測試
@Test public void sayHello1() { // 默認(rèn)說你好 speakService.sayHello(); // 將國家設(shè)置為美國,再說你好 sayHelloFactory.setCountryCode(CountryCode.USA); speakService.sayHello(); // 將國家設(shè)置為德國,再說你好 sayHelloFactory.setCountryCode(CountryCode.GERMANY); speakService.sayHello(); // 將國家設(shè)置為中國,再說你好 sayHelloFactory.setCountryCode(CountryCode.CHINA); speakService.sayHello(); }
測試結(jié)果如下:
您好
hello
Hallo
您好
在解決問題時,只所有我們看的不夠遠(yuǎn),可能是由于自己站的不夠高。同樣的問題,困惑我了多日,直到近期系統(tǒng)的學(xué)習(xí)設(shè)計(jì)模式
、angular官方教程
、Spring 實(shí)戰(zhàn)
后,結(jié)合近期項(xiàng)目變更帶來的新需求,才在使用設(shè)計(jì)模式解決此問題上有所啟發(fā)。
以上是“spring-boot下滿足多生產(chǎn)環(huán)境中個性化定制功能的案例”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。