介绍:
责任链模式为请求创建一个接收者对象链,每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把请求传给下一个接收者。
UML:
角色:
- Handler : 抽象类,定义一个抽象方法:handleRequest,子类实现。
- ConcreteHandler:具体请求的处理者,如果满足当前Handler的限制条件,则处理,继续向下传递。
- Client:设置不同实现类的层级,也就是处理的顺序。
应用场景:
- Zuul中的filter
- Tomcat中的filter
- Tomcat中的部分容器组件
demo简单叙述:
关键类:
final类:ApplicationFilterChain、接口:FilterChain、管理filter的类:ApplicationFilterConfig
关键方法:
FilterChain的doFilter方法、ApplicationFilterChain的internalDoFilter方法。
设置不同filter执行的顺序方法:
采用一个ApplicationFilterConfig类型的数组(数组是有序的),ApplicationFilterConfig里面会有一个Fillter的引用。
关键代码:
private void internalDoFilter(ServletRequest request,
ServletResponse response)
throws IOException, ServletException {
// Call the next filter if there is one
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++];
try {
Filter filter = filterConfig.getFilter();//@1
filter.doFilter(request, response, this);//@2
} catch (IOException | ServletException | RuntimeException e) {
throw e;
} catch (Throwable e) {
e = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(e);
throw new ServletException(sm.getString("filterChain.filter"), e);
}
return;
}
// We fell off the end of the chain -- call the servlet instance
try {
servlet.service(request, response);//@3
}
} catch (IOException | ServletException | RuntimeException e) {
throw e;
} catch (Throwable e) {
e = ExceptionUtils.unwrapInvocationTargetException(e);
ExceptionUtils.handleThrowable(e);
throw new ServletException(sm.getString("filterChain.servlet"), e);
} finally {
if (ApplicationDispatcher.WRAP_SAME_OBJECT) {
lastServicedRequest.set(null);
lastServicedResponse.set(null);
}
}
}
@1、@2、@3:@3代表filter执行完之后,最终会执行servlet的service方法,还是会回归到业务层面,filter仅仅是用来扩展和补充一些额外的逻辑,还有listener的功能也和filter类似...
总结:
责任链模式相对来说不是那么的复杂,一般是一组对象都可能会处理当前的请求,关键就是看请求是否符合对象的限制条件,符合就处理,不符合,就跳过。
这些对象一般都是按照一定顺序处理的,一层一层的调用下去...设置这些对象的顺序的方法可以很灵活,最基础的就是先new 出来所有参与的对象,然后通过setHandler的方式去设置这种引用关系。
像Tomcat中ApplicationFilterChain很明显就是借用数组这种数据结构的特性来设置。
Zuul中的filter用的好像是用一个返回int类型的方法来设置的。
思考问题方法:
WHAT--->HOW--->WHY...
未来舞台很大,要自信,自己其实是可以做很多东西的...