重学 Java 设计模式:实战外观模式
===================
在 Java 开发中,设计模式是一种十分常见的编程思想,它可以帮助我们解决很多实际开发中的问题。本篇文章将介绍一种常见的设计模式——外观模式,并结合实际的开发场景进行讲解。本文将以 SpringBoot 开发门面模式中间件,实现一个统一控制接口白名单的场景来展示外观模式的应用。
什么是外观模式?
外观模式是一种结构型设计模式,它可以为一组复杂的子系统提供一个简单的接口。通过使用外观模式,我们可以将系统中的复杂逻辑隐藏起来,并对外提供简单的接口。外部调用者无需关心具体的执行细节,只需要调用外观方法即可。外观模式可以减少系统的耦合度,提高系统的可维护性和可扩展性。
SpringBoot 开发门面模式中间件
在实际的开发中,我们可能会遇到这样的需求:需要对系统中的接口进行控制,只允许某些特定的 IP 地址访问特定的接口,这时候,外观模式就可以帮助我们实现这个功能。
我们可以使用 SpringBoot 开发一个门面模式中间件,让中间件来完成接口的白名单控制。中间件会检查访问的 IP 地址是否在白名单列表中。如果是,则继续请求,如果不在,则直接返回错误信息。
接下来,我们将一步步地实现这个中间件,以介绍外观模式的应用。
中间件基本流程
在实现中间件之前,我们需要先确定中间件的基本流程。具体来说,我们需要实现一个方法 handle
,这个方法需要根据配置的白名单列表,对传入的 HTTP 请求进行判断,如果 IP 地址在白名单列表中,则正常处理请求。否则,直接返回错误信息。代码如下所示:
public interface GatewayFilter {
void handle(HttpServletRequest request, HttpServletResponse response, GatewayFilterChain filterChain) throws ServletException, IOException;
}
在这个方法中,我们需要调用 filterChain.doFilter
方法来处理请求,同时需要使用 response
对象来返回错误信息。
中间件的具体实现
现在,我们已经确定了中间件的基本流程,接下来,我们需要根据这个流程来实现具体的中间件。在这个例子中,我们使用了 SpringBoot 开发工具来实现代码的自动配置功能。
首先,需要创建一个 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;
}
}
然后,需要创建一个 GatewayFilter
接口,并实现白名单过滤逻辑。
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.");
}
}
// 验证当前 IP 是否在白名单列表中
private boolean validateIp(String remoteAddr) {
if (allowList == null || allowList.isEmpty()) {
return true;
}
return allowList.contains(remoteAddr);
}
}
在这里,我们从请求头中获取了客户端的 IP 地址,并使用 validateIp
方法来判断这个 IP 是否在白名单列表中。如果符合要求,则调用 filterChain.doFilter
方法进行下一步处理。否则,直接返回错误信息。
最后,需要创建一个 GatewayAutoConfiguration
类,用于自动配置当前的中间件。
@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;
}
}
在这个类中,我们使用 @ConditionalOnProperty
来控制中间件是否开启,使用 @ConfigurationProperties
来读取配置的白名单配置信息,并使用 GatewayFilterImpl
类来处理请求。
使用中间件
使用该中间件很简单,只需要在 application.properties
中配置白名单列表即可。例如:
# application.properties
gateway.enabled=true
gateway.allowList=127.0.0.1,192.168.1.2
在这里,我们配置了两个 IP 地址,分别是 127.0.0.1
和 192.168.1.2
。如果请求的 IP 地址不在这个列表中,则无法访问 API。
总结
--
外观模式是一种常见的设计模式,它可以为一组复杂的子系统提供一个简单的接口。通过使用外观模式,我们可以将系统中的复杂逻辑隐藏起来,并对外提供简单的接口,从而减少系统的耦合度,提高系统的可维护性和可扩展性。
在本文中,我们以 SpringBoot 开发门面模式中间件为例,展示了外观模式的应用。通过对请求进行白名单过滤,来限制客户端对接口的访问。通过合理地使用外观模式,我们可以减少开发工作量,提高代码的可重用性和可维护性。
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!