詳解Java設(shè)計(jì)模式之外觀模式
重學(xué) Java 設(shè)計(jì)模式:實(shí)戰(zhàn)外觀模式
在 Java 開發(fā)中,設(shè)計(jì)模式是一種十分常見的編程思想,它可以幫助我們解決很多實(shí)際開發(fā)中的問題。本篇文章將介紹一種常見的設(shè)計(jì)模式——外觀模式,并結(jié)合實(shí)際的開發(fā)場景進(jìn)行講解。本文將以 SpringBoot 開發(fā)門面模式中間件,實(shí)現(xiàn)一個(gè)統(tǒng)一控制接口白名單的場景來展示外觀模式的應(yīng)用。
什么是外觀模式?
外觀模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它可以為一組復(fù)雜的子系統(tǒng)提供一個(gè)簡單的接口。通過使用外觀模式,我們可以將系統(tǒng)中的復(fù)雜邏輯隱藏起來,并對(duì)外提供簡單的接口。外部調(diào)用者無需關(guān)心具體的執(zhí)行細(xì)節(jié),只需要調(diào)用外觀方法即可。外觀模式可以減少系統(tǒng)的耦合度,提高系統(tǒng)的可維護(hù)性和可擴(kuò)展性。
SpringBoot 開發(fā)門面模式中間件
在實(shí)際的開發(fā)中,我們可能會(huì)遇到這樣的需求:需要對(duì)系統(tǒng)中的接口進(jìn)行控制,只允許某些特定的 IP 地址訪問特定的接口,這時(shí)候,外觀模式就可以幫助我們實(shí)現(xiàn)這個(gè)功能。
我們可以使用 SpringBoot 開發(fā)一個(gè)門面模式中間件,讓中間件來完成接口的白名單控制。中間件會(huì)檢查訪問的 IP 地址是否在白名單列表中。如果是,則繼續(xù)請(qǐng)求,如果不在,則直接返回錯(cuò)誤信息。
接下來,我們將一步步地實(shí)現(xiàn)這個(gè)中間件,以介紹外觀模式的應(yīng)用。
中間件基本流程
在實(shí)現(xiàn)中間件之前,我們需要先確定中間件的基本流程。具體來說,我們需要實(shí)現(xiàn)一個(gè)方法 handle,這個(gè)方法需要根據(jù)配置的白名單列表,對(duì)傳入的 HTTP 請(qǐng)求進(jìn)行判斷,如果 IP 地址在白名單列表中,則正常處理請(qǐng)求。否則,直接返回錯(cuò)誤信息。代碼如下所示:
public interface GatewayFilter {
?
? ?void handle(HttpServletRequest request, HttpServletResponse response, GatewayFilterChain filterChain) throws ServletException, IOException;
?
}在這個(gè)方法中,我們需要調(diào)用 filterChain.doFilter 方法來處理請(qǐng)求,同時(shí)需要使用 response 對(duì)象來返回錯(cuò)誤信息。
中間件的具體實(shí)現(xiàn)
現(xiàn)在,我們已經(jīng)確定了中間件的基本流程,接下來,我們需要根據(jù)這個(gè)流程來實(shí)現(xiàn)具體的中間件。在這個(gè)例子中,我們使用了 SpringBoot 開發(fā)工具來實(shí)現(xiàn)代碼的自動(dòng)配置功能。
首先,需要?jiǎng)?chuàng)建一個(gè) GatewayProperties 類來保存配置的白名單列表。
@ConfigurationProperties("gateway")
public class GatewayProperties {
? ?// 配置白名單列表
? ?private List<String> allowList = new ArrayList<>();
?
? ?public List<String> getAllowList() {
? ? ? ?return allowList;
? }
?
? ?public void setAllowList(List<String> allowList) {
? ? ? ?this.allowList = allowList;
? }
}然后,需要?jiǎng)?chuàng)建一個(gè) GatewayFilter 接口,并實(shí)現(xiàn)白名單過濾邏輯。
public class GatewayFilterImpl implements GatewayFilter {
?
? ?public static final String X_REAL_IP = "X-Real-IP";
? ?private List<String> allowList;
?
? ?public GatewayFilterImpl(List<String> allowList) {
? ? ? ?this.allowList = allowList;
? }
?
? ?@Override
? ?public void handle(HttpServletRequest request, HttpServletResponse response, GatewayFilterChain filterChain) throws ServletException, IOException {
? ? ? ?String remoteAddr = request.getHeader(X_REAL_IP);
? ? ? ?if (validateIp(remoteAddr)) {
? ? ? ? ? ?filterChain.doFilter(request, response);
? ? ? } else {
? ? ? ? ? ?response.sendError(HttpStatus.UNAUTHORIZED.value(), "Your IP address is not allowed to access the API.");
? ? ? }
? }
?
? ?// 驗(yàn)證當(dāng)前 IP 是否在白名單列表中
? ?private boolean validateIp(String remoteAddr) {
? ? ? ?if (allowList == null || allowList.isEmpty()) {
? ? ? ? ? ?return true;
? ? ? }
?
? ? ? ?return allowList.contains(remoteAddr);
? }
}在這里,我們從請(qǐng)求頭中獲取了客戶端的 IP 地址,并使用 validateIp 方法來判斷這個(gè) IP 是否在白名單列表中。如果符合要求,則調(diào)用 filterChain.doFilter 方法進(jìn)行下一步處理。否則,直接返回錯(cuò)誤信息。
最后,需要?jiǎng)?chuàng)建一個(gè) GatewayAutoConfiguration 類,用于自動(dòng)配置當(dāng)前的中間件。
@Configuration
@ConditionalOnClass(GatewayFilter.class)
@ConditionalOnProperty(prefix = "gateway", name = "enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(GatewayProperties.class)
public class GatewayAutoConfiguration {
?
? ?@Bean
? ?public GatewayFilter gatewayFilter(GatewayProperties gatewayProperties) {
? ? ? ?return new GatewayFilterImpl(gatewayProperties.getAllowList());
? }
?
? ?@Bean
? ?public FilterRegistrationBean registration(GatewayFilter gatewayFilter) {
? ? ? ?FilterRegistrationBean registration = new FilterRegistrationBean();
? ? ? ?registration.setFilter(gatewayFilter);
? ? ? ?registration.addUrlPatterns("/*");
? ? ? ?registration.setName("gatewayFilter");
? ? ? ?registration.setOrder(Ordered.LOWEST_PRECEDENCE);
? ? ? ?return registration;
? }
?
}在這個(gè)類中,我們使用 @ConditionalOnProperty 來控制中間件是否開啟,使用 @ConfigurationProperties 來讀取配置的白名單配置信息,并使用 GatewayFilterImpl 類來處理請(qǐng)求。
使用中間件
使用該中間件很簡單,只需要在 application.properties 中配置白名單列表即可。例如:
# application.properties ? gateway.enabled=true gateway.allowList=127.0.0.1,192.168.1.2
在這里,我們配置了兩個(gè) IP 地址,分別是 127.0.0.1 和 192.168.1.2。如果請(qǐng)求的 IP 地址不在這個(gè)列表中,則無法訪問 API。
總結(jié)
外觀模式是一種常見的設(shè)計(jì)模式,它可以為一組復(fù)雜的子系統(tǒng)提供一個(gè)簡單的接口。通過使用外觀模式,我們可以將系統(tǒng)中的復(fù)雜邏輯隱藏起來,并對(duì)外提供簡單的接口,從而減少系統(tǒng)的耦合度,提高系統(tǒng)的可維護(hù)性和可擴(kuò)展性。
在本文中,我們以 SpringBoot 開發(fā)門面模式中間件為例,展示了外觀模式的應(yīng)用。通過對(duì)請(qǐng)求進(jìn)行白名單過濾,來限制客戶端對(duì)接口的訪問。通過合理地使用外觀模式,我們可以減少開發(fā)工作量,提高代碼的可重用性和可維護(hù)性。
以上就是詳解Java設(shè)計(jì)模式之外觀模式的詳細(xì)內(nèi)容,更多關(guān)于Java 外觀模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java創(chuàng)建Web項(xiàng)目以及沒有web.xml的解決方法
本文詳細(xì)介紹了如何在Eclipse中創(chuàng)建Web項(xiàng)目并自動(dòng)生成web.xml,提供了直接生成、新建項(xiàng)目時(shí)勾選、手動(dòng)創(chuàng)建Web.xml三種方法,重點(diǎn)在于web.xml的作用和常見問題解決方案,2026-01-01
Java實(shí)現(xiàn)Web應(yīng)用中的定時(shí)任務(wù)(實(shí)例講解)
下面小編就為大家分享一篇Java實(shí)現(xiàn)Web 應(yīng)用中的定時(shí)任務(wù)的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-11-11
解析Java中的定時(shí)器及使用定時(shí)器制作彈彈球游戲的示例
這篇文章主要介紹了Java中的定時(shí)器及使用定時(shí)器制作彈彈球游戲的示例,文中同時(shí)也分析了定時(shí)器timer的缺點(diǎn)及相關(guān)替代方案,需要的朋友可以參考下2016-02-02
雪花算法(snowflak)生成有序不重復(fù)ID的Java實(shí)現(xiàn)代碼
雪花算法是一種分布式系統(tǒng)中生成唯一ID的方法,由41位時(shí)間戳、10位機(jī)器碼和12位序列號(hào)組成,具有唯一性、有序性和高效率等優(yōu)點(diǎn),這篇文章主要介紹了雪花算法(snowflak)生成有序不重復(fù)ID的Java實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2024-11-11
POI導(dǎo)出Excel報(bào)錯(cuò)No such file or directory的解決方法
這篇文章主要為大家詳細(xì)介紹了POI導(dǎo)出Excel報(bào)錯(cuò)No such file or directory的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
SpringBoot+RabbitMQ實(shí)現(xiàn)消息可靠傳輸詳解
消息的可靠傳輸是面試必問的問題之一,保證消息的可靠傳輸主要在生產(chǎn)端開啟?comfirm?模式,RabbitMQ?開啟持久化,消費(fèi)端關(guān)閉自動(dòng)?ack?模式。本文將詳解SpringBoot整合RabbitMQ如何實(shí)現(xiàn)消息可靠傳輸,需要的可以參考一下2022-05-05
spring cglib 與 jdk 動(dòng)態(tài)代理
本篇文章主要介紹了spring cglib與jdk動(dòng)態(tài)代理的相關(guān)知識(shí),具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-05-05

