开源框架中的责任链模式实践( 三 )

说明:

  • 在servlet的doDispatch方法中依次触发责任链的applyPreHandle的前置处理方法、applyPostHandle的后置处理方法 。
  • 前置处理方法applyPreHandle会遍历责任链上的处理器从前往后依次处理,后置处理方法applyPostHandle会遍历责任链上的处理器从后往前依次处理 。
  • 处理器的驱动由责任链对象负责依次触发,非处理器对象自驱执行 。
3.2 Servlet Filter3.2.1 Filter介绍
开源框架中的责任链模式实践

文章插图
  • Servlet过滤器是在JAVA Servlet规范2.3中定义的,它能够对Servlet容器的请求和响应对象进行检查和修改 , 是个典型的责任链 。
  • 在Servlet被调用之前检查Request对象并支持修改Request Header和Request内容 。
  • 在Servlet被调用之后检查Response对象并支修改Response Header和Response内容 。
3.2.2 处理器介绍
public interface Filter {public void init(FilterConfig filterConfig) throws ServletException;public void doFilter ( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException;public void destroy();}public class TimeFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("time filter init");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 1、执行处理的逻辑System.out.println("time filter doFilter");// 2、执行责任链当中的下一个 Filter 对象,等价于执行 FilterChain 的internalDoFilter方法filterChain.doFilter(servletRequest, servletResponse);}}说明:
  • Servlet过滤器类要实现javax.servlet.Filter接口,该接口定义了通用的3个方法 。
  • init方法:负责Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例过程中调用这个方法 。
  • doFilter方法:当客户请求访问与过滤器关联的URL时,Servlet容器会调用该方法 。
  • destroy方法:Servlet容器在销毁过滤器实例前调用该方法,可以释放过滤器占用的资源 。
3.2.3 责任链构建
public final class ApplicationFilterChain implements FilterChain {// 责任链上 Filter 的维护对象private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];//责任链上待执行的 Filter 对象private int pos = 0;// 责任链上拥有的 Filter 数量private int n = 0;void addFilter(ApplicationFilterConfig filterConfig) {// 避免重复添加Filterfor(ApplicationFilterConfig filter:filters)if(filter==filterConfig)return;// 按需进行扩容if (n == filters.length) {ApplicationFilterConfig[] newFilters =new ApplicationFilterConfig[n + INCREMENT];System.arraycopy(filters, 0, newFilters, 0, n);filters = newFilters;}// 保存Filter 对象filters[n++] = filterConfig;}}说明:
  • ApplicationFilterChain作为Filter的责任链,负责责任链的构建和执行 。
  • 责任链通过ApplicationFilterConfig类型的数组对象filters保存Filter处理器 。
  • 责任链上处理器的添加通过保存到数组filters来实现 。
3.2.4 责任链执行
public final class ApplicationFilterChain implements FilterChain {// 责任链上 Filter 的维护对象private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];//责任链上待执行的 Filter 对象private int pos = 0;// 责任链上拥有的 Filter 数量private int n = 0;// 责任链的执行private void internalDoFilter(ServletRequest request,ServletResponse response)throws IOException, ServletException {// 在责任链未执行完的情况下执行责任链if (pos < n) {// 获取当前待执行的 Filter , 同时递增下一次待执行责任链的下标ApplicationFilterConfig filterConfig = filters[pos++];try {Filter filter = filterConfig.getFilter();if( Globals.IS_SECURITY_ENABLED ) {// 省略相关代码} else {filter.doFilter(request, response, this);}} catch (Throwable e) {}return;}try {if ((request instanceof HttpServletRequest) &&(response instanceof HttpServletResponse) &&Globals.IS_SECURITY_ENABLED ) {// 执行正常的业务逻辑} else {servlet.service(request, response);}} catch (Throwable e) {e = ExceptionUtils.unwrapInvocationTargetException(e);throw new ServletException(sm.getString("filterChain.servlet"), e);}}}


推荐阅读