设计模式——责任链模式(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);
				}
			}
		}
	}
}

三、其他设计模式

创建型模式
结构型模式

行为型模式

相关推荐
程序员爱钓鱼8 分钟前
BlackHole 2ch:macOS无杂音录屏与系统音频采集完整技术指南
前端·后端·设计模式
小小8程序员19 分钟前
Spring Boot AOP 全面解析(原理 + 实战 + 场景)
java·spring boot·spring
syt_101323 分钟前
设计模式之-观察者模式
观察者模式·设计模式
何中应32 分钟前
【面试题-8】Spring/Spring MVC/Spring Boot/Spring Cloud
java·spring boot·后端·spring·mvc·面试题
没什么本事1 小时前
Springboot CGLIB 代理对象问题
java·spring boot·spring
Javatutouhouduan1 小时前
SpringBoot整合reids之JSON序列化文件夹操作
java·spring boot·spring·bootstrap·html·后端开发·java架构师
她说..1 小时前
Spring AOP场景5——异常处理(附带源码)
java·数据库·后端·spring·springboot·spring aop
醇氧1 小时前
springAI学习 (二) 模型
java·学习·spring·ai·ai编程
0和1的舞者1 小时前
《MyBatis 从入门到上手:超全基础操作 + XML 配置指南》
数据库·spring boot·学习·spring·mybatis·框架·开发
漂亮的小碎步丶1 小时前
【4】Spring Boot项目中Spring核心容器原理详解
java·后端·spring