设计模式——责任链模式(Chain of Responsibility Pattern)+ Spring相关源码

文章目录

  • 一、责任链模式定义
  • 二、例子
    • [2.1 菜鸟教程](#2.1 菜鸟教程)
      • [2.1.1 定义一个抽象日志类](#2.1.1 定义一个抽象日志类)
      • [2.1.2 定义日志类的具体实现类ConsoleLogger 、ErrorLogger 、FileLogger](#2.1.2 定义日志类的具体实现类ConsoleLogger 、ErrorLogger 、FileLogger)
      • [2.1.3 将日志类串起来,并使用](#2.1.3 将日志类串起来,并使用)
    • [2.2 JDK源码------Filter](#2.2 JDK源码——Filter)
    • [2.3 Spring源码------HandlerInterceptor](#2.3 Spring源码——HandlerInterceptor)
  • 三、其他设计模式

一、责任链模式定义

类型: 行为型模式

每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
目的: 职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

个人理解:上面菜鸟教程说职责链将发送者和请求的处理者解耦,但个人觉得职责链更多的是将多个责任解耦,使用时将所需要的责任组织成责任链。

二、例子

2.1 菜鸟教程

菜鸟教程是以一个日志类为例子。

2.1.1 定义一个抽象日志类

java 复制代码
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);
   
}

2.1.2 定义日志类的具体实现类ConsoleLogger 、ErrorLogger 、FileLogger

java 复制代码
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);
   }
}
java 复制代码
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);
   }
}
java 复制代码
public class FileLogger extends AbstractLogger {
 
   public FileLogger(int level){
      this.level = level;
   }
 
   @Override
   protected void write(String message) {    
      System.out.println("File::Logger: " + message);
   }
}

2.1.3 将日志类串起来,并使用

java 复制代码
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.");
   }
}

2.2 JDK源码------Filter

java 复制代码
public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    default void destroy() {
    }
}

2.3 Spring源码------HandlerInterceptor

java 复制代码
public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
java 复制代码
public class HandlerExecutionChain {

	@Nullable
	private HandlerInterceptor[] interceptors;

	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = 0; i < interceptors.length; i++) {
				HandlerInterceptor interceptor = interceptors[i];
				if (!interceptor.preHandle(request, response, this.handler)) {
					triggerAfterCompletion(request, response, null);
					return false;
				}
				this.interceptorIndex = i;
			}
		}
		return true;
	}

	void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {

		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = interceptors.length - 1; i >= 0; i--) {
				HandlerInterceptor interceptor = interceptors[i];
				interceptor.postHandle(request, response, this.handler, mv);
			}
		}
	}

	void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
			throws Exception {

		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = this.interceptorIndex; i >= 0; i--) {
				HandlerInterceptor interceptor = interceptors[i];
				try {
					interceptor.afterCompletion(request, response, this.handler, ex);
				}
				catch (Throwable ex2) {
					logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
				}
			}
		}
	}
}

三、其他设计模式

创建型模式
结构型模式

行为型模式

相关推荐
AI人工智能+电脑小能手7 小时前
大白话说Java设计模式-26-策略模式(业务实战篇)
java·spring·设计模式·策略模式·支付系统·算法切换
刀锋00019 小时前
Java 工程师转 AI Agent 最短路径:用 Spring 的思维理解 Spring AI 2.0(附 LangChain4j 对照)
java·人工智能·spring boot·spring·ai agent
重生之我是Java开发战士10 小时前
【Java EE】Spring AOP :面向切面编程
java·spring·java-ee
凤山老林10 小时前
基于 Spring Batch 的海量数据迁移与批处理架构:分片、容错与断点续跑
java·spring boot·spring·架构·spring batch
gis开发之家11 小时前
Spring Boot 4 深度解析——参数接收大全:@RequestParam、@PathVariable、@RequestBody
java·spring boot·后端·spring
(轻舟已过万重山)11 小时前
D1 · 融合蓝图:Spring AI + 虚拟线程 + 服务网格——现代后端统一底座
java·人工智能·spring
星火102412 小时前
【Groovy翻译-进阶篇】Groovy 中的设计模式
后端·设计模式·groovy
音符犹如代码12 小时前
Varnish Cache 实战:反向代理缓存原理与 VCL 配置
java·spring·缓存
shuoshuohaohao13 小时前
Spring6
java·spring
SL_staff13 小时前
风控规则如何从硬编码解耦?我们在 JVS-Rules 中的实践与思考
java·spring boot·设计模式