网站建设相关资质,网站域名空间地址,山东房地产新闻,如何网页优化设计模式的应用——《职责链模式》 一、职责链模式基础知识#xff08;What、Why、How#xff09;1、什么是职责链模式#xff1f;2、如何使用职责链模式#xff1f;——它的原理和实现3、为什么用职责链模式#xff1f; 二、什么场景下使用它#xff1f;——职责链模式在… 设计模式的应用——《职责链模式》 一、职责链模式基础知识What、Why、How1、什么是职责链模式2、如何使用职责链模式——它的原理和实现3、为什么用职责链模式 二、什么场景下使用它——职责链模式在框架和实际工作中的应用Servlet FilterSpring InterceptorDubbo Filter 三、总结与思考1、Filter、Interceptor、AOP 都可以实现访问控制功能它们之间的不同点是什么2、和职责链模式相似的设计模式有哪些3、职责链模式经常与哪些设计模式配合使用 一、职责链模式基础知识What、Why、How
1、什么是职责链模式 职责链模式是一种行为型设计模式。它的目标在于将请求的发送和接收解耦让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链并沿着这条链传递这个请求直到链上的某个接收对象能够处理它为止。 2、如何使用职责链模式——它的原理和实现
在我们实际的应用过程中职责链模式有如下两种
将所有处理者连成一条链并沿着这条链传递请求直到有对象处理它为止。请求会被所有的处理器都处理一遍不存在中途终止的情况。
如上两类职责链仅仅是在处理方式上不一样其他的都是一样的。我们的职责链模式主要包含两个角色抽象处理者、具体处理者 我们要实现一个职责链模式首先我们需要创建一个抽象处理者类Handler它包含一个指向下一个处理者的引用。然后我们创建具体处理者类ConcreteHandlerA和ConcreteHandlerB它们分别实现抽象处理者类的方法。最后我们创建一个客户端类Client它负责将请求传递给处理者链中的下一个处理者。 以下是第一类情况的示例代码
import java.util.ArrayList;
import java.util.List;// 抽象处理者类
abstract class Handler {protected Handler successor;public void setSuccessor(Handler successor) {this.successor successor;}public abstract void handleRequest(String request);
}// 具体处理者A类
class ConcreteHandlerA extends Handler {Overridepublic void handleRequest(String request) {if (request.equals(A)) {System.out.println(ConcreteHandlerA处理请求);} else {if (successor ! null) {successor.handleRequest(request);} else {System.out.println(没有合适的处理器处理请求);}}}
}// 具体处理者B类
class ConcreteHandlerB extends Handler {Overridepublic void handleRequest(String request) {if (request.equals(B)) {System.out.println(ConcreteHandlerB处理请求);} else {if (successor ! null) {successor.handleRequest(request);} else {System.out.println(没有合适的处理器处理请求);}}}
}// 客户端类
class Client {private ListHandler handlers new ArrayList();public Client() {handlers.add(new ConcreteHandlerA());handlers.add(new ConcreteHandlerB());for (int i 0; i handlers.size() - 1; i) {handlers.get(i).setSuccessor(handlers.get(i 1));}}public void sendRequest(String request) {for (Handler handler : handlers) {handler.handleRequest(request);}}
}public class Main {public static void main(String[] args) {Client client new Client();client.sendRequest(A); // 输出ConcreteHandlerA处理请求client.sendRequest(B); // 输出ConcreteHandlerB处理请求client.sendRequest(C); // 输出没有合适的处理器处理请求}
}
3、为什么用职责链模式
既然我们用它那我们就要讲讲它的优点啦职责链模式有如下优点
请求与处理解耦 在职责链模式中处理者只需关心自己的处理逻辑如果不是自己的处理的请求直接转发降低了对象间的耦合性。 链式传递功能 一个请求可以在一条链上进行传递直到链上的某一个节点决定处理此请求。这种结构使得请求者无须了解链路的结构只需要将请求发送出去等待结果返回即可。 易于维护和拓展 由于职责链模式遵循开闭原则可以灵活地修改链路结构比如新增或删除环境。另外 可以灵活动态的选择需要哪些职责。 增强系统的可扩展性 符合开闭原则当我们需要添加新的职责时我们只需添加新的职责类并且添加到执行链中去即可。而无需修改其他代码。 二、什么场景下使用它——职责链模式在框架和实际工作中的应用
职责链在很多框架中都有使用下面仅介绍在Servlet Filter、Spring Interceptor以及dubbo Filter中的使用。
Servlet Filter
Servlet Filter是Java Web开发中用于对请求和响应进行处理的过滤器。它可以在请求到达目标资源之前或响应返回客户端之前执行一些操作例如验证用户身份、记录日志、压缩响应等。Servlet Filter通常通过实现javax.servlet.Filter接口来定义。 以下是一个简单的Servlet Filter示例 import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public class MyFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化过滤器时执行的操作例如加载配置文件}Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 在请求到达目标资源之前执行的操作System.out.println(请求被MyFilter处理);// 继续执行过滤器链中的下一个过滤器或目标资源chain.doFilter(request, response);// 在响应返回客户端之后执行的操作System.out.println(响应被MyFilter处理);}Overridepublic void destroy() {// 销毁过滤器时执行的操作例如释放资源}
} 要使用这个过滤器需要在web.xml文件中进行配置 filterfilter-namemyFilter/filter-namefilter-classcom.example.MyFilter/filter-class
/filter
filter-mappingfilter-namemyFilter/filter-nameurl-pattern/*/url-pattern
/filter-mapping
Spring Interceptor
在Spring框架中拦截器Interceptor是一种用于处理请求和响应的机制。通过使用拦截器我们可以实现职责链模式将多个拦截器按照顺序组合起来以便在一个请求到达目标资源之前或之后执行特定的操作。 以下是一个简单的示例展示了如何在Spring拦截器中使用职责链模式 1、首先创建一个拦截器接口HandlerInterceptor并定义一个方法preHandle该方法将在请求到达目标资源之前执行 public interface HandlerInterceptor {boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler);
} 2、然后创建一个具体的拦截器类MyInterceptor实现HandlerInterceptor接口并在preHandle方法中实现职责链模式的逻辑 import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {private HandlerInterceptor nextInterceptor;public MyInterceptor(HandlerInterceptor nextInterceptor) {this.nextInterceptor nextInterceptor;}Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 在这里实现你的职责链逻辑System.out.println(MyInterceptor: preHandle);// 如果当前拦截器没有处理完请求将请求传递给下一个拦截器if (nextInterceptor ! null) {return nextInterceptor.preHandle(request, response, handler);}// 如果当前拦截器已经处理完请求返回truereturn true;}
} 3、接下来创建一个配置类WebMvcConfig用于注册拦截器并配置拦截器的执行顺序 import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;Configuration
public class WebMvcConfig implements WebMvcConfigurer {Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册第一个拦截器并设置其执行顺序为1registry.addInterceptor(new MyInterceptor(null)).addPathPatterns(/**).order(1);// 注册第二个拦截器并设置其执行顺序为2registry.addInterceptor(new MyInterceptor(new MyInterceptor(null))).addPathPatterns(/**).order(2);}
} 在这个示例中我们创建了两个拦截器MyInterceptor并将它们按照顺序添加到拦截器注册表中。当一个请求到达目标资源时Spring会按照拦截器的执行顺序依次调用它们的preHandle方法。如果某个拦截器没有处理完请求它会将请求传递给下一个拦截器。 Dubbo Filter
Dubbo中的过滤器Filter是一种用于处理请求和响应的中间件。它可以在服务提供者和消费者之间对请求进行预处理、后处理或者拦截从而实现对请求和响应的定制化处理。Dubbo支持多种类型的过滤器如 协议过滤器Protocol Filter用于处理请求和响应的序列化和反序列化例如将Java对象转换为JSON字符串或将JSON字符串转换为Java对象。 路由过滤器Routing Filter用于根据条件选择不同的服务提供者或消费者例如基于权重、随机、轮询等策略进行负载均衡。 指标过滤器Metrics Filter用于收集和统计服务的调用次数、响应时间等信息以便进行性能监控和优化。 限流过滤器RateLimiting Filter用于限制服务的调用速率以防止系统过载。 安全过滤器Security Filter用于验证请求的身份信息例如使用OAuth2、JWT等认证机制。 要使用过滤器需要在Dubbo配置文件中进行配置。例如使用dubbo:protocol标签配置协议过滤器 dubbo:protocol namedubbo port20880 /
dubbo:protocol namehttp port8080 filterstatistic / 在这个例子中我们为Dubbo协议配置了一个名为statistic的过滤器该过滤器会在请求和响应之间收集统计信息。 下面是Dubbo中RandomRouterFilterWrapper的源码 该类继承自AbstractRouter并实现了route方法。在route方法中首先通过扩展点获取随机路由过滤器如果存在则调用其route方法进行路由如果不存在则使用默认的路由规则。同时还实现了getAlgorithmName和compare方法分别返回算法名称和比较结果。 import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.router.AbstractRouter;
import org.apache.dubbo.rpc.router.RouteRule;import java.util.List;
import java.util.Random;public class RandomRouterFilterWrapper extends AbstractRouter {private final Random random new Random();Overridepublic ListRouteRule route(ListRouteRule rules, RpcContext context) {// 获取扩展点中的随机路由过滤器RandomRouterFilter filter ExtensionLoader.getExtensionLoader(RandomRouterFilter.class).getExtension(Constants.DEFAULT_EXTENSION_NAME);if (filter ! null) {return filter.route(rules, context);}// 如果没有配置随机路由过滤器则使用默认的路由规则return super.route(rules, context);}Overridepublic String getAlgorithmName() {return random;}Overridepublic int compare(String o1, String o2) {return random.nextInt(2) - 1;}
}
三、总结与思考
职责链设计模式常常在开发框架中使用用来实现框架的过滤器、拦截器功能让框架的使用者在不需要对源码进行修改的情况下添加新的过滤拦截功能体现了开闭原则。但具体每个框架的实现会根据实际的需求来设计。下面是关于职责链模式的一些思考分享给大家
1、Filter、Interceptor、AOP 都可以实现访问控制功能它们之间的不同点是什么
Filter、Interceptor和AOP都可以实现访问控制功能这是它们的相同点。然而它们在实现和使用上存在一些不同点。 过滤器(Filter)属于Servlet规范主要拦截web访问的url地址。其工作原理基于Tomcat提供的接口直接对请求和响应进行处理。 拦截器(Interceptor)依赖于Spring框架主要拦截以.action结尾的url以及Action的访问。拦截器关注的是接口执行前和执行后要做的事并且只能拦截controller的请求。 Spring AOP拦截器是基于Spring AOP实现的它只能拦截Spring管理Bean的访问如业务层Service。与过滤器和拦截器不同的是Spring AOP关注的是方法执行前后要做的事情。 该三者的拦截顺序是分级的优先级从高到低依次是Filter、Interceptor、AOP。但在某些特殊情况下也可以通过调整配置来改变这个顺序。例如在Spring Boot中可以通过配置文件来改变拦截器的执行顺序。
2、和职责链模式相似的设计模式有哪些 命令模式Command Pattern此模式也是一种行为型模式类似于职责链模式它也通过将请求封装成对象来达到解耦的目的。不过命令模式中的命令对象会包含与请求相关的信息比如请求的接收者、方法名等。 解释器模式Interpreter Pattern该模式同样属于行为型模式它通过定义语言的文法以及解析规则来解析语言。这与职责链模式中多个处理者按顺序处理请求的方式相似。 中介者模式Mediator Pattern这是一种结构型模式它通过引入一个中介者对象来解除原有对象之间的依赖关系从而降低系统的耦合度。这与职责链模式中的处理者链条有异曲同工之妙。 观察者模式Observer Pattern这也是一种行为型模式它通过定义一对多的通知机制来实现当一个对象状态改变时所有依赖于它的对象都会得到通知并自动更新。这和职责链模式中每个处理者都只负责处理自己感兴趣的请求然后将其转发给后续的处理者的思想很相似。
3、职责链模式经常与哪些设计模式配合使用
简单工厂模式在创建处理者对象时可以使用简单工厂模式来封装对象的创建过程和逻辑。观察者模式可以在处理者中加入对其他处理者的引用然后动态的插入和移除后续处理者以改变处理顺序。单例模式对于某些需要保证唯一性的处理者可以采用单例模式来确保在整个系统中只有一个实例存在。模板方法模式可以在一个处理者的基类中定义一些算法的框架而将具体实现延迟到子类中。这样客户端可以通过调用基类的算法接口来达到处理请求的目的而不需要直接访问子类。