29 | 比较:Jetty如何实现具有上下文信息的责任链?
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
Jetty实现了具有上下文信息的责任链,通过HandlerWrapper实现了责任链模式,形成了一个链表。Jetty还实现了“回溯”的链式调用,即从头到尾依次链式调用Handler的方法A,完成后再回到头节点,再进行一次链式调用,调用另一个方法B。Jetty是通过ScopedHandler来实现这一点的,ScopedHandler是HandlerWrapper的子类,它引入了_outScope和_nextScope变量,用来控制doScope方法和doHandle方法的调用顺序。通过设置这些值,并在代码中判断这些值并采取相应的动作,ScopedHandler帮助搭建了调用框架,让Handler链上的doScope方法在doHandle、handle方法之前执行。这样Jetty的子类只需要实现doScope和doHandle方法,从而实现了具有上下文信息的责任链。ContextHandler是ScopedHandler的子类,实现了doScope和doHandle方法,维护了ServletContext和Web应用的初始化参数,完成了请求的修正、类加载器的设置,并调用nextScope。在doHandle方法里分别完成了相应的请求处理工作。Jetty中的ScopedHandler通过递归的方式来设置_outScope和_nextScope两个变量,然后通过判断这些值来控制调用的顺序。另外,ScopedHandler通过线程私有数据ThreadLocal来保存变量,既达到了传递变量的目的,又没有线程安全的问题。Jetty的doStart方法将线程私有变量__outerScope设置成null,以完成相应的操作。Jetty的实现原理涉及了递归和线程私有数据的使用,对于理解递归的精髓和线程安全有着重要意义。
《深入拆解 Tomcat & Jetty 》,新⼈⾸单¥68
全部留言(7)
- 最新
- 精选
- neohope最后的问题,应该是这样的: protected void doStart() throws Exception { try{ _outerScope=__outerScope.get(); if (_outerScope==null){ //本次处理的第一个scope handler //告知后续scope handler,_outerScope选我 __outerScope.set(this); } super.doStart(); _nextScope= getChildHandlerByClass(ScopedHandler.class); } finally { if (_outerScope==null){ //本次处理结束 //为了下次同一个线程处理是, //还能正常的设置第一个scope handler //必须把threadlocal变量设为null __outerScope.set(null); } } } 此外,这一节里有一个non scoped handler X,一开始没太看懂调阅顺序。 后来发现是这样的: public final void nextHandle(String target...)... { if (_nextScope!=null && _nextScope==_handler){ //上面条件可以保证下一个handler是scope handler _nextScope.doHandle(target,baseRequest,request, response); } else if (_handler!=null){ //non scpoe handler调用下一个handler的 super.handle(target,baseRequest,request,response); } } 感觉类成员的命名不太合适, 比如__outerScope和_outerScope 比如_handler其实一直指向的是下一个handler,是不是该为_nextHandler更好一些?
作者回复: 给你的钻研精神点赞👍
2019-07-239 - despacitoScopedHandler 会有不同的实现类,而__outerScope 是ScopedHandler里static的变量,如果不设置为null,那么不同的子类实例执行doStrat()方法的时候,会有问题2019-07-166
- 帽子丨影感觉jetty的源码写的好混乱,经常没有注释,一个类也通常扩展3/4个接口功能,还各种循环嵌套。好难懂。。。2019-09-265
- 往事随风,顺其自然可以重新处理下一次请求2019-07-163
- nightmare每一次请求的请求链互不影响2019-07-163
- 绍棠threadlocal为什么在每次请求结束需要设置为null:为了下次请求复用。因为线程是用池化技术,下次请求优先共用线程,而不是新建线程2020-04-161
- Fredo1. 防止影响下个请求数据 2. 用完即清理,防内存泄露2024-02-06归属地:广东