网站值不值得做seo,网站服务器有哪些类型有哪些类型有哪些类型有哪些类型有哪些,广州网络运营课程培训班,永康建设局网站电话责任链模式适用于需要将请求和处理解耦的场景#xff0c;同时又需要动态地组织处理逻辑的场景。 通过使用责任链模式#xff0c;可以实现请求的动态处理、灵活的扩展和简化的代码编写#xff0c;提高系统的可维护性和可扩展性。
一、责任链入门
以下这是GPT生成的责任链代…责任链模式适用于需要将请求和处理解耦的场景同时又需要动态地组织处理逻辑的场景。 通过使用责任链模式可以实现请求的动态处理、灵活的扩展和简化的代码编写提高系统的可维护性和可扩展性。
一、责任链入门
以下这是GPT生成的责任链代码
1.定义抽象处理器接口
// 定义抽象处理者接口
interface Handler {void handleRequest(int request);void setNextHandler(Handler handler);
}2. 具体处理者类1
class ConcreteHandler1 implements Handler {// 定义第二个处理器private Handler nextHandler;Overridepublic void handleRequest(int request) {if (request 0 request 10) {System.out.println(ConcreteHandler1 处理请求 request);} else if (nextHandler ! null) {nextHandler.handleRequest(request);}}Overridepublic void setNextHandler(Handler handler) {this.nextHandler handler;}
}3. 具体处理者类2
class ConcreteHandler2 implements Handler {private Handler nextHandler;Overridepublic void handleRequest(int request) {if (request 10 request 20) {System.out.println(ConcreteHandler2 处理请求 request);} else if (nextHandler ! null) {nextHandler.handleRequest(request);}}Overridepublic void setNextHandler(Handler handler) {this.nextHandler handler;}
}4. 客户端类
public class Client {public static void main(String[] args) {// 创建具体处理者对象Handler handler1 new ConcreteHandler1();Handler handler2 new ConcreteHandler2();// 设置处理者之间的关系handler1.setNextHandler(handler2);// 创建请求并发送给责任链的第一个处理者handler1.handleRequest(5);handler1.handleRequest(15);handler1.handleRequest(25);}
}在这个示例中Handler 是抽象处理者接口定义了处理请求的方法 handleRequest 和设置下一个处理者的方法 setNextHandler。ConcreteHandler1 和 ConcreteHandler2 是具体处理者类分别处理不同范围的请求。Client 是客户端类创建具体处理者对象并设置它们之间的关系然后发送请求给责任链的第一个处理者。当请求发送到责任链后责任链中的处理者按顺序尝试处理请求直到有一个处理者处理了请求为止。 handler1.handleRequest(15); 表示将请求值为15的请求发送给责任链的第一个处理者 handler1。在当前设计的责任链模式中一旦有一个处理者处理了请求处理链就会终止不再将请求传递给下一个处理者。因此每次发送请求后只有第一个能够处理该请求的处理者会对其进行处理。因为具体的实现类中是通过if...else进行处理器的整合的当然也可以修改为只要满足特定的处理条件处理器就会继续往下走。
责任链作为一种设计模式目的是为了让代码更加优雅复用性更高。
二、上下文责任链
1. 定义订单处理器模板接口
public interface OrderProcessor {// 自定义void processOrder(Order order, OrderContext context);// 公共方法void preRequestHandler(Order order);
}2. 定义订单处理器抽象类模板
实现公共方法
public abstract class AbstractOrderProcessor implements OrderProcessor {Overridepublic void preRequestHandler(Order order) {System.out.println(采购员对订单统一处理);}
}3. 订单处理器实现
3.1 开始处理器
Component
HandlerOrder(order 1)
public class PendingOrderProcessor extends AbstractOrderProcessor {Overridepublic void processOrder(Order order, OrderContext context) {// 处理待处理的订单逻辑System.out.println(开始订单处理: order.getId());// 可以通过上下文对象访问共享信息System.out.println(Context: context.getInfo());}
}3.2 批准处理器
Component
HandlerOrder(order 2)
public class ApprovedOrderProcessor extends AbstractOrderProcessor{Overridepublic void processOrder(Order order, OrderContext context) {// 处理已批准的订单逻辑System.out.println(批准订单: order.getId());// 可以通过上下文对象访问共享信息System.out.println(Context: context.getInfo());}
}3.3 发货处理器
Component
HandlerOrder(order 3)
public class ShippedOrderProcessor extends AbstractOrderProcessor{Overridepublic void processOrder(Order order, OrderContext context) {// 处理已发货的订单逻辑System.out.println(订单发货: order.getId());// 可以通过上下文对象访问共享信息System.out.println(Context: context.getInfo());}
}4. 订单责任链
Component
public class OrderProcessorChain {private final ApplicationContext applicationContext;CollectionOrderProcessor processors new ArrayList();// 注入 ApplicationContextpublic OrderProcessorChain(ApplicationContext applicationContext) {this.applicationContext applicationContext;// 获取所有订单处理器this.processors applicationContext.getBeansOfType(OrderProcessor.class).values();}// 根据注解值进行排序protected ListOrderProcessor getProcessors() {return this.processors.stream().sorted((o1, o2) - {HandlerOrder order1 o1.getClass().getAnnotation(HandlerOrder.class);HandlerOrder order2 o2.getClass().getAnnotation(HandlerOrder.class);if (order1 null order2 null) {return 0; // 如果两者都没有注解则认为它们相等} else if (order1 null) {return 1; // 如果 o1 没有注解但 o2 有注解则 o1 排在 o2 前面} else if (order2 null) {return -1; // 如果 o1 有注解但 o2 没有注解则 o1 排在 o2 后面} else {return Integer.compare(order1.order(), order2.order()); // 比较两个注解的 order 属性}}).collect(Collectors.toList());}public void process(Order order, OrderContext context) {ListOrderProcessor processors getProcessors();// 依次调用订单处理器处理订单for (OrderProcessor processor : processors) {processor.preRequestHandler(order);processor.processOrder(order, context);}}
}5. 实体类和注解
Data
public class Order { private int id;
}Data
public class OrderContext {private String info; // 上下文信息
}// 指定注解的保留策略
Retention(RetentionPolicy.RUNTIME)
public interface HandlerOrder {int order();
}6. 测试
SpringBootTest
public class OrderProcessorChainTest {Autowiredprivate OrderProcessorChain processorChain;Testpublic void testOrderProcessing() {// 创建订单Order order new Order();order.setId(123);// 创建订单上下文对象OrderContext context new OrderContext();context.setInfo(Some info for processing orders);// 处理订单processorChain.process(order, context);}
}结果 采购员对订单统一处理 开始订单处理: 123 Context: Some info for processing orders 采购员对订单统一处理 批准订单: 123 Context: Some info for processing orders 采购员对订单统一处理 订单发货: 123 Context: Some info for processing orders 三、Spring过滤器链
责任链在Spring中怎么运用呢 在Spring框架中责任链模式常常运用在拦截器Interceptor和过滤器Filter等场景中用于处理HTTP请求、消息传递等。
拦截器Interceptor在Spring MVC中拦截器用于在处理请求之前或之后执行一些操作比如权限检查、日志记录等。你可以定义多个拦截器它们按照顺序构成一个责任链。当一个请求到达时会依次执行每个拦截器的预处理方法和后处理方法类似于责任链模式的行为。
过滤器Filter在Spring框架中你也可以使用Servlet过滤器来对HTTP请求进行预处理或后处理。过滤器链在Servlet容器中会按照配置顺序依次执行也可以看作是一个责任链模式的应用。
事件监听器Event ListenerSpring框架提供了事件监听器机制你可以定义自己的事件和监听器并通过Spring容器进行管理。当某个事件发生时监听器会按照注册顺序依次被调用类似于责任链模式。
下面是一个简单的Spring拦截器示例
1. 定义拦截器
public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在请求处理之前执行的操作比如权限检查未登录则直接拦截if (!checkAuth(request)) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);return false;}// 放行return true;}// 可以不重写该方法Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在请求处理之后执行的操作}// 可以不重写该方法Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在请求完成之后执行的操作}private boolean checkAuth(HttpServletRequest request) {// 检查用户是否有权限// 这里假设简单地检查请求中是否包含合法的身份验证信息String authToken request.getHeader(Authorization);return authToken ! null authToken.equals(valid_token);}
}在这个示例中 LoginInterceptor 类实现了 HandlerInterceptor 接口它是Spring MVC中的拦截器。preHandle 方法用于在请求处理之前执行操作比如权限检查postHandle 和 afterCompletion 方法分别用于在请求处理之后执行操作。多个拦截器可以组成一个责任链按照它们的注册顺序依次执行。 代码中只是提供了拦截器的实现但是并没有形成责任链那么多个拦截器是如何形成链路并进行请求的处理的呢
2. 过滤器链配置
Configuration
public class MvcConfig implements WebMvcConfigurer {Resourceprivate StringRedisTemplate stringRedisTemplate;Resourceprivate EmployeeService employeeService;Overridepublic void addInterceptors(InterceptorRegistry registry) {// 登录拦截器registry.addInterceptor(new LoginInterceptor(stringRedisTemplate)).excludePathPatterns(/user/login,/employee/login).order(2);// 管理员拦截器用户可操作的功能都排除registry.addInterceptor(new AdminLoginInterceptor(employeeService)).excludePathPatterns(/user/login,/user/logout).order(3);// token刷新的拦截器,order值越小越先执行这个拦截器对所有请求都执行registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns(/**).order(1);}}在上面的代码中MvcConfig 实现了 WebMvcConfigurer 类并且通过addInterceptors方法项过滤器链中增加了两个拦截器LoginInterceptor 和 AdminLoginInterceptor。这两个拦截器通过order指定了拦截器的顺序。两个拦截器在请求过来时都会触发拦截器会根据自身配置的拦截路径做过滤处理。 我们可以来看下 WebMvcConfigurer接口的定义接口定义了很多方法其中有一个addInterceptors方法就是将拦截器添加到链路中的。这个接口其实有点像我们在责任链入门中讲到的定义抽象处理器接口中的setNextHandler通过registry.addInterceptor()来将处理器进行组织。
public interface WebMvcConfigurer {... default void addInterceptors(InterceptorRegistry registry) {}
}InterceptorRegistry类中会通过addInterceptor方法将处理器添加到集合中去。
public class InterceptorRegistry {private final ListInterceptorRegistration registrations new ArrayList();private static final ComparatorObject INTERCEPTOR_ORDER_COMPARATOR;public InterceptorRegistry() {}public InterceptorRegistration addInterceptor(HandlerInterceptor interceptor) {InterceptorRegistration registration new InterceptorRegistration(interceptor);this.registrations.add(registration);return registration;}
}通过addInterceptors方法将拦截器添加到Spring MVC的拦截器链中。当Spring MVC接收到一个请求时它会通过DispatcherServlet进行处理。DispatcherServlet会调用拦截器链中的每个拦截器来处理请求。
具体来说以下是请求如何经过拦截器链被拦截器处理的过程
当一个请求到达DispatcherServlet时DispatcherServlet会创建一个用于处理该请求的HandlerExecutionChain。
在创建HandlerExecutionChain的过程中DispatcherServlet会检查是否存在拦截器链。如果存在DispatcherServlet会将该请求与拦截器链关联起来。
在处理请求之前DispatcherServlet会依次调用拦截器链中每个拦截器的preHandle方法。拦截器的preHandle方法可以用来进行预处理比如身份验证、日志记录等操作。
如果拦截器链中的所有拦截器的preHandle方法都返回true表示请求可以继续处理。此时DispatcherServlet会调用与请求匹配的处理器(Controller)来处理请求。
处理器处理完请求后DispatcherServlet会依次调用拦截器链中每个拦截器的postHandle方法。拦截器的postHandle方法可以用来进行后处理比如修改响应内容等操作。
最后DispatcherServlet会依次调用拦截器链中每个拦截器的afterCompletion方法。拦截器的afterCompletion方法会在请求完成后被调用无论请求是否成功处理。
通过这个过程拦截器能够在请求处理的不同阶段进行干预实现诸如权限验证、日志记录、异常处理等功能。拦截器链的顺序由拦截器的order方法决定数值越小的拦截器优先级越高。
四、总结
关于责任链模式必须要有处理器模板要有链链可以是集合也可以是类似链表。请求就会沿着这条链依次被链上处理器处理。