使用职责链模式进行Spring Boot开发

前言

职责链模式是一种行为型设计模式,它允许将请求沿着处理链进行传递,直到有一个处理者能够处理该请求。职责链模式将请求的发送者和接收者解耦,使得多个对象都有机会处理请求。

在Spring Boot开发中,职责链模式可以用于解耦复杂的业务逻辑,将其拆分为多个处理者,每个处理者负责处理特定的请求。

实现

开发例子

请求处理链

在Spring Boot中,我们可能需要处理一系列的请求,每个请求需要经过多个处理者进行处理。使用职责链模式,我们可以将请求处理链条化,每个处理者只关注自己负责处理的请求,并将未能处理的请求传递给下一个处理者。

public interface RequestHandler {
  void handleRequest(Request request);
}

public class FirstHandler implements RequestHandler {
  private RequestHandler nextHandler;
  
  @Override
  public void handleRequest(Request request) {
    if (request.isHandled()) {
      System.out.println("Request already handled");
    } else if (request.getType() == RequestType.TYPE1) {
      System.out.println("Handling request type 1");
      request.setHandled(true);
    } else {
      passToNextHandler(request);
    }
  }
  
  private void passToNextHandler(Request request) {
    if (nextHandler != null) {
      nextHandler.handleRequest(request);
    }
  }
}

public class SecondHandler implements RequestHandler {
  private RequestHandler nextHandler;
  
  @Override
  public void handleRequest(Request request) {
    if (request.isHandled()) {
      System.out.println("Request already handled");
    } else if (request.getType() == RequestType.TYPE2) {
      System.out.println("Handling request type 2");
      request.setHandled(true);
    } else {
      passToNextHandler(request);
    }
  }
  
  private void passToNextHandler(Request request) {
    if (nextHandler != null) {
      nextHandler.handleRequest(request);
    }
  }
}

public enum RequestType {
  TYPE1,
  TYPE2,
  // 其他请求类型
}

public class Request {
  private RequestType type;
  private boolean handled;
  
  // Getter and setter methods
}

通过职责链模式,我们可以将多个请求处理者串联成一个处理链,并在每个处理者中判断是否能够处理当前的请求。如果能处理,则进行处理;否则将请求传递给下一个处理者。

RequestHandler firstHandler = new FirstHandler();
RequestHandler secondHandler = new SecondHandler();

firstHandler.setNextHandler(secondHandler);

Request request1 = new Request(RequestType.TYPE1);
firstHandler.handleRequest(request1);

Request request2 = new Request(RequestType.TYPE2);
firstHandler.handleRequest(request2);

过滤器链

在Spring Boot开发中,我们可能需要对请求进行过滤和处理。使用职责链模式,我们可以将请求过滤器串联成一个过滤器链,每个过滤器负责处理特定的请求,并将请求传递给下一个过滤器。

public interface RequestFilter {
  void filter(HttpServletRequest request, HttpServletResponse response, FilterChain chain);
}

public class AuthenticationFilter implements RequestFilter {
  @Override
  public void filter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
    // 进行身份验证的逻辑
    // 如果通过验证,可以继续处理;否则返回错误响应
    chain.doFilter(request, response);
  }
}

public class LoggingFilter implements RequestFilter {
  @Override
  public void filter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
    // 进行请求日志记录的逻辑
    chain.doFilter(request, response);
  }
}

public interface FilterChain {
  void doFilter(HttpServletRequest request, HttpServletResponse response);
}

public class DefaultFilterChain implements FilterChain {
  private List<RequestFilter> filters = new ArrayList<>();
  private int currentFilter = 0;
  
  public void addFilter(RequestFilter filter) {
    filters.add(filter);
  }
  
  @Override
  public void doFilter(HttpServletRequest request, HttpServletResponse response) {
    if (currentFilter < filters.size()) {
      RequestFilter filter = filters.get(currentFilter);
      currentFilter++;
      filter.filter(request, response, this);
    }
  }
}

通过职责链模式,我们可以将多个请求过滤器串联成一个过滤器链,并在每个过滤器中进行请求处理。每个过滤器都可以选择继续处理请求或中断处理。

RequestFilter authFilter = new AuthenticationFilter();
RequestFilter loggingFilter = new LoggingFilter();

FilterChain filterChain = new DefaultFilterChain();
filterChain.addFilter(authFilter);
filterChain.addFilter(loggingFilter);

filterChain.doFilter(request, response);

使用职责链模式实现日志记录

假设我们有三种级别的日志记录器:ErrorLogger,FileLogger和ConsoleLogger,我们可以使用职责链模式来实现它们。

首先,定义一个抽象的记录器类

public abstract class AbstractLogger {
    public static int INFO = 1;
    public static int DEBUG = 2;
    public static int ERROR = 3;

    protected int level;

    //责任链中的下一个元素
    protected AbstractLogger nextLogger;

    public void setNextLogger(AbstractLogger nextLogger){
        this.nextLogger = nextLogger;
    }

    public void logMessage(int level, String message){
        if(this.level <= level){
            write(message);
        }
        if(nextLogger != null){
            nextLogger.logMessage(level, message);
        }
    }

    abstract protected void write(String message);
}

然后,创建具体的记录器类:

public class ConsoleLogger extends AbstractLogger {
    public ConsoleLogger(int level){
        this.level = level;
    }

    @Override
    protected void write(String message) {        
        System.out.println("Standard Console::Logger: " + message);
    }
}

public class ErrorLogger extends AbstractLogger {
    public ErrorLogger(int level){
        this.level = level;
    }

    @Override
    protected void write(String message) {        
        System.out.println("Error Console::Logger: " + message);
    }
}

public class FileLogger extends AbstractLogger {
    public FileLogger(int level){
        this.level = level;
    }

    @Override
    protected void write(String message) {
        System.out.println("File::Logger: " + message);
    }
}

最后,创建职责链:

public class ChainPatternDemo {
   
   private static AbstractLogger getChainOfLoggers(){

      AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
      AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
      AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);

      errorLogger.setNextLogger(fileLogger);
      fileLogger.setNextLogger(consoleLogger);

      return errorLogger;  
   }

   public static void main(String[] args) {
      AbstractLogger loggerChain = getChainOfLoggers();

      loggerChain.logMessage(AbstractLogger.INFO, 
         "This is an information.");

      loggerChain.logMessage(AbstractLogger.DEBUG, 
         "This is a debug level information.");

      loggerChain.logMessage(AbstractLogger.ERROR, 
         "This is an error information.");
   }
}

在这个示例中,不同的日志器可以处理不同级别的日志信息。如果一个日志器无法处理某个请求,那么这个请求就会被传递给链中的下一个对象。

请求分发

职责链模式的一个常见应用场景是请求的分发处理。在Spring Boot 3应用中,我们可以使用职责链模式来实现请求的分发和处理。

首先,我们定义一个抽象处理器Handler,该处理器包含一个抽象方法handleRequest用于处理请求:

public abstract class Handler {
    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handleRequest(Request request);
}

然后,我们创建具体的处理器类ConcreteHandler,该类继承自抽象处理器Handler,并实现handleRequest方法:

public class ConcreteHandler extends Handler {
    public void handleRequest(Request request) {
        if (canHandle(request)) {
            // 处理请求的逻辑
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }

    private boolean canHandle(Request request) {
        // 判断是否能够处理该请求的逻辑
    }
}

在上述代码中,ConcreteHandler类首先判断是否能够处理该请求,如果能够处理,则执行相应的处理逻辑;如果不能处理,则将请求传递给下一个处理器successor。

最后,我们在Spring Boot应用中配置和使用职责链模式:

@Configuration
public class AppConfig {
    @Bean
    public Handler handlerChain() {
        Handler handler1 = new ConcreteHandler();
        Handler handler2 = new ConcreteHandler();
        Handler handler3 = new ConcreteHandler();

        handler1.setSuccessor(handler2);
        handler2.setSuccessor(handler3);

        return handler1;
    }
}

通过以上配置,我们成功地在Spring Boot 3应用中使用职责链模式实现了请求的分发。每个处理器根据自身的逻辑判断是否能够处理该请求,如果能够处理,则执行相应的处理逻辑;如果不能处理,则将请求传递给下一个处理器。

权限校验

职责链模式的另一个应用场景是权限校验。在Spring Boot 3应用中,我们可以使用职责链模式来实现权限校验功能。

假设我们有一个权限校验接口PermissionChecker,该接口定义了检查用户权限的方法:

public interface PermissionChecker {
    boolean checkPermission(User user, String permission);
}

然后,我们创建具体的权限校验处理器类PermissionCheckerHandler,该类继承自抽象处理器Handler,并实现handleRequest方法:

public class PermissionCheckerHandler extends Handler {
    private PermissionChecker permissionChecker;

    public PermissionCheckerHandler(PermissionChecker permissionChecker) {
        this.permissionChecker = permissionChecker;
    }

    public void handleRequest(Request request) {
        if (canHandle(request)) {
            User user = request.getUser();
            String permission = request.getPermission();

            if (permissionChecker.checkPermission(user, permission)) {
                // 权限校验通过,执行相应的处理逻辑
            } else if (successor != null) {
                successor.handleRequest(request);
            } else {
                // 权限校验未通过,返回错误信息
            }
        }
    }

    private boolean canHandle(Request request) {
        // 判断是否能够处理该请求的逻辑
    }
}

在上述代码中,PermissionCheckerHandler类在处理请求时,首先判断是否能够处理该请求,如果能够处理,则进行权限校验。如果权限校验通过,则执行相应的处理逻辑;如果权限校验未通过,则返回错误信息;如果无法处理该请求,则将请求传递给下一个处理器。

最后,我们在Spring Boot应用中配置和使用职责链模式:

@Configuration
public class AppConfig {
    @Bean
    public Handler handlerChain(PermissionChecker permissionChecker) {
        Handler handler1 = new PermissionCheckerHandler(permissionChecker);
        Handler handler2 = new ConcreteHandler();
        Handler handler3 = new ConcreteHandler();

        handler1.setSuccessor(handler2);
        handler2.setSuccessor(handler3);

        return handler1;
    }
}

通过以上配置,我们成功地在Spring Boot 3应用中使用职责链模式实现了权限校验功能。每个处理器根据自身的逻辑判断是否能够处理该请求,如果能够处理,则进行权限校验;如果权限校验通过,则执行相应的处理逻辑;如果权限校验未通过,则返回错误信息;如果无法处理该请求,则将请求传递给下一个处理器。

总结

通过使用职责链模式,我们可以实现请求处理和日志记录等功能,将请求发送者和接收者解耦,提高代码的灵活性和可维护性。

本篇文章由AI生成