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

前言

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

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

实现

开发例子

请求处理链

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
}

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

1
2
3
4
5
6
7
8
9
10
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开发中,我们可能需要对请求进行过滤和处理。使用职责链模式,我们可以将请求过滤器串联成一个过滤器链,每个过滤器负责处理特定的请求,并将请求传递给下一个过滤器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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);
}
}
}

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

1
2
3
4
5
6
7
8
9
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,我们可以使用职责链模式来实现它们。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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);
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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);
}
}

最后,创建职责链:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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用于处理请求:

1
2
3
4
5
6
7
8
9
public abstract class Handler {
protected Handler successor;

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

public abstract void handleRequest(Request request);
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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应用中配置和使用职责链模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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,该接口定义了检查用户权限的方法:

1
2
3
4
public interface PermissionChecker {
boolean checkPermission(User user, String permission);
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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应用中配置和使用职责链模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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生成