博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
过滤器模式之servlet过滤器和mybaits的intercept
阅读量:4075 次
发布时间:2019-05-25

本文共 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 List
filters = 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 List
interceptors = 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/

你可能感兴趣的文章
postgresql监控工具pgstatspack的安装及使用
查看>>
postgresql查看表的和索引的情况,判断是否膨胀
查看>>
postgresql中根据oid和filenode去找表的物理文件的位置
查看>>
postgresql减少wal日志生成量的方法
查看>>
swift中单例的创建及销毁
查看>>
获取App Store中App的ipa包
查看>>
iOS 关于pods-frameworks.sh:permission denied报错的解决
查看>>
设置RGBColor
查看>>
设置tabbaritem的title的颜色及按钮图片
查看>>
动态设置label的高度
查看>>
获取 一个文件 在沙盒Library/Caches/ 目录下的路径
查看>>
图片压缩
查看>>
检测缓存文件是否超时
查看>>
十进制字符串转十六进制字符串
查看>>
属性字符串(富文本)的使用
查看>>
cell上label的背景颜色在选中状态下改变的解决办法
查看>>
GPS定位
查看>>
地图、显示用户位置、大头针
查看>>
自定义大头针
查看>>
UIButton添加block点击事件
查看>>