本文共 9523 字,大约阅读时间需要 31 分钟。
一、Servlet的过滤器链(FilterChian)演示
概述:
* 1、主要接口和类
* FilterChian:定义了过滤器链接口 * ApplicationFilterChain :过滤器链实现,内部有过滤器Filters数组和servlet实例的成员变量 * Servlet:封装请求响应的servlet * Request:请求对象 * Response:响应对象 * Filter: 过滤器接口 * 2、执行流程 * ApplicationFilterChain实例将各种filter添加到内部的filters,然后调用doFilter(),doFilter()的功能 * 主要就是从Filters取filter,执行filter的doFilter(request,response,chian),filter的doFilter实际执行了 * 此Filter增加的功能,如果调用chian的doFilter,过滤链就会继续循环调用 直至filters遍历完成,如果filter * 内部不调用chian的doFilter或filters已经遍历完成,此时执行Servlet的service(request, response);3、demo演示:
FilterChian过滤器链接口
interface FilterChian{ void doFilter(Request request, Response response) ; }
过滤器接口
interface Filter{ void doFilter(Request request, Response response, FilterChian chain); }
FilterChian过滤器实现: 用list代替数组实现
static class ApplicationFilterChain implements FilterChian { /** * 演示简化:采用list演示,装所有的Filter */ private Listfilters = new ArrayList (); /** * 计数用途 */ private int pos; /** * 每一个servlet对应所有的filters拦截器 */ private Servlet servlet; @Override public void doFilter(Request request, Response response) { if(pos < filters.size()) { Filter filter = filters.get(pos); pos++; try { filter.doFilter(request, response, this); } catch (Exception e) { throw e; } catch (Throwable e) { e.printStackTrace(); } return; } // 注意上面的return,所有过滤器链全部执行完才会执行servlet servlet.service(request, response); } /** * 添加filters */ public void addFilter(Filter filter) { for (Filter old : filters) { if(filter.equals(old)) { return; } } this.filters.add(filter); } /** * 添加servlet */ public void setServlet(Servlet servlet) { this.servlet = servlet; } /** * 释放 */ public void release() { filters.clear(); pos = 0; servlet = null; } }
模拟servlet
static class Servlet { public void service(Request request ,Response response){ System.out.println(request.getMsg()); System.out.println(response.getMsg()); } }
模拟request
static class Request { public Request(String msg) { super(); this.msg = msg; } private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
模拟response
static class Response{ private String msg; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
测试:
/** * 测试: * 通过ApplicationFilterChain组装1个servlet+所有的过滤器filters。 * 每个filter如果不执行doFilter,那么就执行流程中断,但是本filter会全部执行完成! * filter代码执行流程是: one before, two before - > two end , one end 的流程! */ public static void main(String[] args) { Request request = new Request("base request"); Response response = new Response(); Servlet servlet = new Servlet(); ApplicationFilterChain appChain = new ApplicationFilterChain(); appChain.addFilter((req, res, chain) -> { // 添加过滤器1号 String msg = req.getMsg(); msg+= ":one filter handler"; req.setMsg(msg); System.out.println("1号过滤器前置执行"); chain.doFilter(req, res); // 这里注释掉,2号过滤器和servlet不执行,但是本filter会执行完。 System.out.println("1号过滤器后置执行"); }); appChain.addFilter((req, res, chain) -> { // 添加过滤器2号 String msg = req.getMsg(); msg+= ":two filter handler"; req.setMsg(msg); System.out.println("2号过滤器前置执行"); chain.doFilter(req, res); System.out.println("2号过滤器后置执行"); }); appChain.setServlet(servlet); // 添加servlet // 过滤器链执行 -- 过滤器 --- servlet appChain.doFilter(request, response); // 打印结果// 1号过滤器前置执行// 2号过滤器前置执行// base request:one filter handler:two filter handler// null// 2号过滤器后置执行// 1号过滤器后置执行 }
二、MyBaits的过滤器链(Plugin)演示
概述:
mybaits拦截器是通过Plugin生成代理类的方式持续包装目标类target, Plugin类实际上的增强方法是intercepter接口实现定义的增强方法,再编写Interceptor类时定义注解Intercepts含有需要拦截方法和类的声明。
执行流程: 由多个Interceptor持续调用Plugin包装目标对象,最后返回代理类,代理类执行时,判断是否拦截方法如果是拦截方法,就由Interceptor增强,后调用下一个puglin包装的target。主要接口和类: Plugin: 主要是实现InvocationHandler增强功能,(实际增强功能调用的是Interceptor,它只是等于抽取了公共创建代理类的相关代码) Interceptor:拦截器接口,实现就是我们自己要增强的功能。 Intercepts、Signature:标注在Interceptor的注解,标识需要拦截的类和方法。 Invocation:target、method、args方法执行的包装 InterceptorChain:组装Interceptor的过滤器链/** * 1、Invocation:方法执行包装 */ static class Invocation { private Object target; private Method method; private Object[] args; public Invocation(Object target, Method method, Object[] args) { this.target = target; this.method = method; this.args = args; } public Object getTarget() { return target; } public Method getMethod() { return method; } public Object[] getArgs() { return args; } public Object proceed() throws InvocationTargetException, IllegalAccessException { return method.invoke(target, args); } } /** * Intercepts注解标记拦截方法 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @interface Intercepts { Signature[] value(); } /** * Signature 注解标注方法签名 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @interface Signature { Class type(); String method(); Class [] args(); } /** * 2、拦截器接口 */ interface Interceptor{ Object intercept(Invocation invocation) throws Throwable; Object plugin(Object target); } /** * 3、拦截器链:添加多个intercepters,用每个Interceptor的plugin包装目标对象target。 */ static class InterceptorChain { private final Listinterceptors = new ArrayList (); public Object pluginAll(Object target) { for (Interceptor interceptor : interceptors) { target = interceptor.plugin(target); } return target; } public void addInterceptor(Interceptor interceptor) { interceptors.add(interceptor); } } /** * 4、Plugin插件 */ static class Plugin implements InvocationHandler{ // 目标类 private Object target; // 拦截器 private Interceptor interceptor; // 标记待拦截类型和方法 private Map , Set > signatureMap; private Plugin(Object target, Interceptor interceptor, Map , Set > signatureMap) { this.target = target; this.interceptor = interceptor;this.signatureMap = signatureMap; } // 根据signatureMap是否存在待拦截方法,存在使用interceptor增强,否则直接执行。 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { Set methods = signatureMap.get(method.getDeclaringClass()); if (methods != null && methods.contains(method)) { return interceptor.intercept(new Invocation(target, method, args)); } return method.invoke(target, args); } catch (Exception e) { throw e; } } // wrap方法对target动态代理:用interceptor对target功能增强 // PluginUtil:详见下面有详细 public static Object wrap(Object target, Interceptor interceptor) { Map , Set > signatureMap = PluginUtil.getSignatureMap(interceptor); Class type = target.getClass(); Class [] interfaces = PluginUtil.getAllInterfaces(type, signatureMap); if (interfaces.length > 0) { return Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)); } return target; } } /** * 5、Plugin中一些静态辅助方法 */ static class PluginUtil { /** * 从Intercepts解析类型和方法的map,class作为key,method的set集合作为value。 */ public static Map , Set > getSignatureMap(Interceptor interceptor) { Intercepts interceptsAnontation = interceptor.getClass().getAnnotation(Intercepts.class); if (interceptsAnontation == null) { throw new RuntimeException("No @Intercepts annotation was found in interceptor "); } Signature[] sigs = interceptsAnontation.value(); Map , Set > signatureMap = new HashMap , Set >(); for (Signature sig : sigs) { Set methods = signatureMap.get(sig.type()); if (methods == null) { methods = new HashSet (); signatureMap.put(sig.type(), methods); } try { Method method = sig.type().getMethod(sig.method(), sig.args()); methods.add(method); } catch (Exception e) { throw new RuntimeException("Could not find method on"+ sig.type() + " named " + sig.method()); } } return signatureMap; } /** * 得到类型所有的接口,如果在signatureMap中存在的话。 */ public static Class [] getAllInterfaces(Class type, Map , Set > signatureMap) { Set > interfaces = new HashSet >(); while (type != null) { for (Class c : type.getInterfaces()) { if (signatureMap.containsKey(c)) { interfaces.add(c); } } type = type.getSuperclass(); } return interfaces.toArray(new Class [interfaces.size()]); } } /// /// 测试 // interface MyTarget { String invoke(); } static class TargetImpl implements MyTarget{ private String name; public String invoke() { return this.name; } public TargetImpl(String name) { super(); this.name = name; } } /** * 拦截器one */ @Intercepts({ @Signature(type = MyTarget.class, method = "invoke", args = {}) }) static class OneInterceptor implements Interceptor{ @Override public Object intercept(Invocation invocation) throws Throwable { Object result = invocation.proceed(); result += ":OneInterceptor"; return result; } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } } /** * 拦截器two */ @Intercepts({ @Signature(type = MyTarget.class, method = "invoke", args = {}) }) static class TwoInterceptor implements Interceptor{ @Override public Object intercept(Invocation invocation) throws Throwable { Object result = invocation.proceed(); result += ":TwoInterceptor"; return result; } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } } /** * 测试使用 */ public static void main(String[] args) { OneInterceptor interceptor1 = new OneInterceptor(); TwoInterceptor interceptor2 = new TwoInterceptor(); InterceptorChain chain = new InterceptorChain(); chain.addInterceptor(interceptor1); chain.addInterceptor(interceptor2); MyTarget plugin = (MyTarget)chain.pluginAll(new TargetImpl("old:")); String invoke = plugin.invoke(); System.out.println(invoke); // old::OneInterceptor:TwoInterceptor }
转载地址:http://neuni.baihongyu.com/