Java责任链模式:优雅解耦系统处理流程,实现高效灵活的请求处理与分发(下)

简介: Java责任链模式:优雅解耦系统处理流程,实现高效灵活的请求处理与分发

3.4 优化方式:使用AOP实现责任链模式

如前所述,在传统的责任链模式实现中,每个处理节点的实现都需要定义一个独立的类,从而增加了代码量和维护难度。为了简化实现,可以使用面向切面编程(AOP)来实现责任链模式。

在AOP中,可以使用切面来定义责任链模式中每个节点的处理逻辑,并将这些切面连接成一个链式结构。当需要进行请求处理时,只需要按顺序将这些切面逐个执行,就可以实现责任链模式的功能。

使用AOP可以避免定义大量的类文件,简化代码实现,同时也提高了代码的执行效率。此外,AOP还提供了更加灵活的配置方式,可以根据业务需求对责任链结构进行动态配置,支持动态增加、删除节点对象。由此,AOP实现的责任链模式具有更高的可扩展性和灵活性。

示例代码:

// 定义切面,定义每个节点的处理逻辑  
@Aspect  
public class Responsibilities {  
    // 定义处理请求的切入点  
    @Pointcut("execution(* com.example.Application.*(..))")  
    public void handleRequest() {  
        // 声明需要执行的切面方法  
        @Before("handleRequest()")  
        public void beforeHandleRequest(JoinPoint joinPoint) {  
            // 获取请求对象  
            Request request = (Request) joinPoint.getArgs()[0];  
            // 执行前置处理逻辑  
            beforeHandleRequest(request);  
            // 执行处理逻辑  
            handleRequest(request);  
            // 执行后置处理逻辑  
            afterHandleRequest(request);  
        }  
    }  
    // 定义处理前置处理逻辑的切面方法  
    @Before("handleRequest()")  
    public void beforeHandleRequest(Request request) {  
        // 执行前置处理逻辑  
        // ...  
    }  
    // 定义处理后置处理逻辑的切面方法  
    @After("handleRequest()")  
    public void afterHandleRequest(Request request) {  
        // 执行后置处理逻辑  
        // ...  
    }  
}
// 定义请求处理类,实现责任链模式  
public class Request {  
    // 处理请求的逻辑  
    public void handleRequest() {  
        // 执行处理逻辑  
        // ...  
    }  
    // 前置处理逻辑  
    public void beforeHandleRequest(Request request) {  
        // 执行前置处理逻辑  
        // ...  
    }  
    // 后置处理逻辑  
    public void afterHandleRequest(Request request) {  
        // 执行后置处理逻辑  
        // ...  
    }  
}
// 应用上下文,声明需要执行的责任链  
@ApplicationContext  
public class ApplicationContext {  
    // 声明需要执行的责任链  
    @Autowired  
    private ResponsibilitiesResponsibilities;  
    // 处理请求的方法  
    public void handleRequest(Request request) {  
        Responsibilities.beforeHandleRequest(request);  
        request.handleRequest();  
        Responsibilities.afterHandleRequest(request);  
    }  
}

在上面的示例代码中,Responsibilities类是切面类,它定义了每个节点的处理逻辑。handleRequest()方法是请求处理类实现的处理方法,它实现了责任链模式的核心功能。beforeHandleRequest()afterHandleRequest()方法是前置处理逻辑和后置处理逻辑,它们被注入到请求处理类中,以便在请求处理类中调用。

四、责任链模式的注意事项

4.1 存在循环调用的风险

在实现责任链模式时,需要注意节点之间的循环调用,避免出现死循环的情况。

循环调用的风险通常出现在两种情况下:一是责任链节点自身会对请求进行多次处理,从而形成死循环;二是责任链节点之间相互调用,出现互相调用的情况。

为了避免循环调用的风险,需要对责任链节点的处理逻辑进行严格的控制和规范,确保节点的处理逻辑只能一次性地对请求进行处理,并且不会出现相互调用的情况。

另外,可以通过设置最大处理次数或者设置超时时间等机制来防止出现死循环,从而避免对系统的影响。

4.2 确定责任链顶端和底端

在实现责任链模式时,需要确定责任链的顶端和底端,以确保请求能够被正确地传递和处理。

责任链的顶端一般是由客户端发起请求的地方,底端则是链的末尾,即最后一个节点的处理逻辑。

在确定责任链的顶端和底端时,需要考虑业务需求和系统结构,避免出现环状结构或节点缺失的情况。

如果责任链没有明确的顶端和底端,则会出现请求无法被正确处理的情况,从而影响系统的正常运行。因此,在实现责任链模式时,需要对节点的逻辑和业务流程进行仔细的分析和设计,并合理地确定责任链的顶端和底端。

五、责任链模式的例子

5.1 实例:多个银行卡支付问题

假设有一个在线支付系统,用户可以选择使用多个银行卡中的任意一张,但是每个银行卡都有不同的支付限制,如下所示:

  • 银行卡A支付限制:每次支付金额不超过500元;
  • 银行卡B支付限制:每日支付金额不超过2000元;
  • 银行卡C支付限制:每月支付金额不超过10000元。

如果用户选择的银行卡支付限制不符合要求,则无法完成支付。为了解决这个问题,可以使用责任链模式,创建一个银行卡支付处理链,根据银行卡的支付限制依次进行处理,直到找到可以完成支付的银行卡。

代码实现:

首先,定义银行卡处理器接口和抽象类。银行卡处理器接口包含一个处理方法,用于判断当前银行卡是否可以完成支付;抽象类实现了银行卡处理器接口,并提供了一个链式处理器的引用,以及一个设置下一个处理器的方法。

public interface BankCardHandler {
    boolean canPay(int amount);
}
public abstract class AbstractBankCardHandler implements BankCardHandler {
    private BankCardHandler nextHandler;
    public BankCardHandler setNextHandler(BankCardHandler handler) {
        this.nextHandler = handler;
        return nextHandler;
    }
    public boolean canPay(int amount) {
        if (check(amount)) {
            return true;
        } else if (nextHandler != null) {
            return nextHandler.canPay(amount);
        } else {
            return false;
        }
    }
    protected abstract boolean check(int amount);
}

然后,创建三个具体的银行卡处理器类,分别处理上述三个场景:

public class BankCardAHandler extends AbstractBankCardHandler {
    protected boolean check(int amount) {
        return amount <= 500;
    }
}
public class BankCardBHandler extends AbstractBankCardHandler {
    private int dailyLimit;
    public BankCardBHandler(int dailyLimit) {
        this.dailyLimit = dailyLimit;
    }
    protected boolean check(int amount) {
        return amount <= dailyLimit;
    }
}
public class BankCardCHandler extends AbstractBankCardHandler {
    private int monthlyLimit;
    public BankCardCHandler(int monthlyLimit) {
        this.monthlyLimit = monthlyLimit;
    }
    protected boolean check(int amount) {
        return amount <= monthlyLimit;
    }
}

最后,组合银行卡处理器类,形成一个处理链:

public class BankCardPayment {
    private BankCardHandler handlerChain;
    public BankCardPayment() {
        handlerChain = new BankCardAHandler();
        handlerChain.setNextHandler(new BankCardBHandler(2000))
            .setNextHandler(new BankCardCHandler(10000));
    }
    public boolean pay(int amount) {
        return handlerChain.canPay(amount);
    }
}

在客户端代码中,创建一个银行卡支付实例,根据用户输入的支付金额进行支付操作:

BankCardPayment payment = new BankCardPayment();
if (payment.pay(300)) {
    System.out.println("支付成功!");
} else {
    System.out.println("支付失败,金额超过所有银行卡的限制!");
}

5.2 实例:Java Web过滤器

Java Web过滤器用于拦截Web请求并对它们进行相应的处理,它可以对特定的请求进行过滤、修改它们的参数、检查用户权限等。下面是一个简单的Java Web过滤器示例,对其代码进行详细说明:

首先,我们需要创建一个实现Filter接口的Java类:

public class MyFilter implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    // 初始化代码
  }
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    // 过滤代码
    chain.doFilter(request, response); // 继续执行其他过滤器或Servlet
  }
  @Override
  public void destroy() {
    // 清理资源代码
  }
}

上面的代码中,我们实现了Filter接口中的三个方法:

  • init方法:在过滤器被初始化时被调用。在这个方法中,我们可以进行一些初始化工作(例如读取配置文件或建立数据库连接等)。
  • doFilter方法:这是过滤器最重要的方法,它会对请求进行过滤处理。我们可以在这个方法中检查请求参数、修改请求或响应数据、检查用户权限等。如果需要,我们还可以使用FilterChain的doFilter方法,将请求传递给链中的下一个过滤器或最终的Servlet。
  • destroy方法:在过滤器被销毁时被调用。在这个方法中,我们可以进行一些清理操作(例如释放资源或关闭数据库连接等)。

在doFilter方法中,我们可以根据需要对请求进行处理。例如,以下代码将检查请求参数中是否包含名为"username"的参数:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  String username = request.getParameter("username");
  if (username != null) {
    // 对于包含username参数的请求,我们可以进行相应的处理
  }
  chain.doFilter(request, response); // 继续执行其他过滤器或Servlet
}

在实际使用中,我们需要将这个过滤器注册到我们的Web应用程序中。以下是一个简单的web.xml配置示例:

<web-app>
  <filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.example.MyFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

以上示例将我们的过滤器注册到应用程序中,并将其映射到所有的URL上。这样,每当有请求访问我们的Web应用程序时,过滤器就会被自动调用。

以上是一个简单的Java Web过滤器的实例和说明。尽管这个示例非常简单,但它可以作为你编写更复杂的过滤器的参考。

六、总结与结论

责任链模式是一种行为型设计模式,用于将多个请求处理器对象连接成一条链,可以让请求沿着这条链不断地传递,直到有一个请求处理器处理完成为止。在责任链模式中,每个请求处理器都可以选择将请求进行处理,或将请求转发给下一个请求处理器,从而将系统中的请求处理逻辑进行解耦,使得请求的发送者和接收者之间的关系更加灵活。

责任链模式的实现方式有单向链表实现和集合迭代器实现,优化方式可以使用函数式编程和AOP来简化实现和提高可扩展性。在使用责任链模式时需要注意存在循环调用的风险和确定责任链的顶端和底端。

在实际应用中,责任链模式可以用于银行卡支付、Java Web过滤器等场景。通过使用责任链模式,可以避免代码耦合度过高,增加代码的可维护性和可扩展性,提高系统的效率和灵活性。

目录
相关文章
|
8月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
603 8
|
8月前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
841 2
|
8月前
|
移动开发 监控 小程序
java家政平台源码,家政上门清洁系统源码,数据多端互通,可直接搭建使用
一款基于Java+SpringBoot+Vue+UniApp开发的家政上门系统,支持小程序、APP、H5、公众号多端互通。涵盖用户端、技工端与管理后台,支持多城市、服务分类、在线预约、微信支付、抢单派单、技能认证、钱包提现等功能,源码开源,可直接部署使用。
592 24
|
8月前
|
安全 前端开发 Java
使用Java编写UDP协议的简易群聊系统
通过这个基础框架,你可以进一步增加更多的功能,例如用户认证、消息格式化、更复杂的客户端界面等,来丰富你的群聊系统。
302 11
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
Java与生成式AI:构建内容生成与创意辅助系统
生成式AI正在重塑内容创作、软件开发和创意设计的方式。本文深入探讨如何在Java生态中构建支持文本、图像、代码等多种生成任务的创意辅助系统。我们将完整展示集成大型生成模型(如GPT、Stable Diffusion)、处理生成任务队列、优化生成结果以及构建企业级生成式AI应用的全流程,为Java开发者提供构建下一代创意辅助系统的完整技术方案。
403 10
|
8月前
|
人工智能 监控 Java
Java与AI智能体:构建自主决策与工具调用的智能系统
随着AI智能体技术的快速发展,构建能够自主理解任务、制定计划并执行复杂操作的智能系统已成为新的技术前沿。本文深入探讨如何在Java生态中构建具备工具调用、记忆管理和自主决策能力的AI智能体系统。我们将完整展示从智能体架构设计、工具生态系统、记忆机制到多智能体协作的全流程,为Java开发者提供构建下一代自主智能系统的完整技术方案。
1025 4
|
8月前
|
机器学习/深度学习 分布式计算 Java
Java与图神经网络:构建企业级知识图谱与智能推理系统
图神经网络(GNN)作为处理非欧几里得数据的前沿技术,正成为企业知识管理和智能推理的核心引擎。本文深入探讨如何在Java生态中构建基于GNN的知识图谱系统,涵盖从图数据建模、GNN模型集成、分布式图计算到实时推理的全流程。通过具体的代码实现和架构设计,展示如何将先进的图神经网络技术融入传统Java企业应用,为构建下一代智能决策系统提供完整解决方案。
664 0
|
8月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
407 1
|
8月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
382 1
|
9月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案