前言
常见的有三种,serverlet ,spring Interceptor, aop 。
serverlet filter实现
图解

使用
public class LogFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 在创建Filter时自动调用,// 其中filterConfig包含这个Filter的配置参数,比如name之类的(从配置文件中读取的)}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("拦截客户端发送来的请求.");chain.doFilter(request, response);System.out.println("拦截发送给客户端的响应.");}@Overridepublic void destroy() {// 在销毁Filter时自动调用}}// 在web.xml配置文件中如下配置:<filter><filter-name>logFilter</filter-name><filter-class>com.xzg.cd.LogFilter</filter-class></filter><filter-mapping><filter-name>logFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
源码实现
实现思路:
1 维护过滤器数组
2 增加时更新数组,并根据需要扩容
3 执行时,递归执行,直到所有完成
public final class ApplicationFilterChain implements FilterChain {private int pos = 0; //当前执行到了哪个filterprivate int n; //filter的个数private ApplicationFilterConfig[] filters;private Servlet servlet;@Overridepublic void doFilter(ServletRequest request, ServletResponse response) {if (pos < n) {ApplicationFilterConfig filterConfig = filters[pos++];Filter filter = filterConfig.getFilter();filter.doFilter(request, response, this);} else {// filter都处理完毕后,执行servletservlet.service(request, response);}}public void addFilter(ApplicationFilterConfig filterConfig) {for (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;}filters[n++] = filterConfig;}}
spring Interceptor
图解

使用代码
public class LogInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("拦截客户端发送来的请求.");return true; // 继续后续的处理}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("拦截发送给客户端的响应.");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("这里总是被执行.");}}//在Spring MVC配置文件中配置interceptors<mvc:interceptors><mvc:interceptor><mvc:mapping path="/*"/><bean class="com.xzg.cd.LogInterceptor" /></mvc:interceptor></mvc:interceptors>
源码实现
public class HandlerExecutionChain {private final Object handler;private HandlerInterceptor[] interceptors;public void addInterceptor(HandlerInterceptor interceptor) {initInterceptorList().add(interceptor);}boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {HandlerInterceptor[] interceptors = getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {for (int i = 0; i < interceptors.length; i++) {HandlerInterceptor interceptor = interceptors[i];if (!interceptor.preHandle(request, response, this.handler)) {triggerAfterCompletion(request, response, null);return false;}}}return true;}void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {HandlerInterceptor[] interceptors = getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {for (int i = interceptors.length - 1; i >= 0; i--) {HandlerInterceptor interceptor = interceptors[i];interceptor.postHandle(request, response, this.handler, mv);}}}void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex)throws Exception {HandlerInterceptor[] interceptors = getInterceptors();if (!ObjectUtils.isEmpty(interceptors)) {for (int i = this.interceptorIndex; i >= 0; i--) {HandlerInterceptor interceptor = interceptors[i];try {interceptor.afterCompletion(request, response, this.handler, ex);} catch (Throwable ex2) {logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);}}}}}
小结与对比
对比
AOP、Servlet Filter、Spring Interceptor这三者可以从不同权限检查的范围大小的视角来应用:
1. Servlet Filter
运维部门需要对只供内部访问的服务进行IP限制或访问审查时,在容器这一层增加一个Filter,在发布时发布系统自动加挂这个Filter,这样对上层应用就是透明的,内网IP地址段增减或审查规则调整都不需要上层应用的开发人员去关心。
2. Spring Interceptor
由框架或基础服务部门来提供的微服务间相互调用的授权检查时,可以提供统一的SDK,由程序员在需要的服务上配置。
3. AOP
业务应用内权限检查,可以把权限检查在统一模块中实现,通过配置由AOP加插拦截检查。
其他类似设计
netty的ChannelPipeline的实现逻辑:
1、每一个SocketChannel对象维护这一个ChannelPipeline对象,该对象支持bind,connect,disconnect,read,write等IO时间的触发链条;
2、ChannelPipeline对外提供ChannelHandler的增删改查的接口、对内使用AbstractChannelHandlerContext对象将ChannelHandler包装了一层,维护了一个AbstractChannelHandlerContext的双向链表。
3、当SocketChannel发生IO事件时,比如发生了read事件,SocketChannel委托ChannelPipeline去处理这些时间,从而启动了责任链的操作。
说明
内容整理自极客《设计模式专栏》
