使用职责链模式进行Spring Boot开发
使用职责链模式进行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应用中使用职责链模式实现了权限校验功能。每个处理器根据自身的逻辑判断是否能够处理该请求,如果能够处理,则进行权限校验;如果权限校验通过,则执行相应的处理逻辑;如果权限校验未通过,则返回错误信息;如果无法处理该请求,则将请求传递给下一个处理器。
总结
通过使用职责链模式,我们可以实现请求处理和日志记录等功能,将请求发送者和接收者解耦,提高代码的灵活性和可维护性。