java 设计模式 拦截器
来源:互联网 发布:linux执行sql文件 编辑:程序博客网 时间:2024/04/26 06:51
拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理。同时,拦截器也可以让你将通用的代码模块化并作为可重用的类。Struts2中的很多特性都是由拦截器来完成的。拦截是AOP的一种实现策略。在Webwork的中文文档的解释为:拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。谈到拦截器,还有一个词大家应该知道——拦截器链(Interceptor
Chain,在Struts 2中称为拦截器栈Interceptor
Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用
为了便于自身理解,我们自己实现一个。
在我们的请求到来之前,加入现在我进入了一个页面,而改页面是需要先检查是否已登录,此时如果我加一个判断的话,就可以很容易实现,但是当我们的页面增多时,那么就该为我们的每个请求页面都加个判断,是相当麻烦的一件事,故此,spring或struts都为我们提供了相应的拦截器,以下是拦截器的实现原理:
首先我们需要定义一个action接口
public interface Action { String execute();}
拦截器接口
public interface Interceptor { void before(ActionInvocation invocation); String intercept(ActionInvocation invocation); void after(ActionInvocation invocation);}
调度器接口
public interface ActionInvocation { String invoke();}
定义我们的拦截器
AroundInterceptor 拦截器
package com.cmh.intercept;import com.cmh.service.ActionInvocation;public class AroundInterceptor implements Interceptor{ @Override public void before(ActionInvocation invocation) { // TODO Auto-generated method stub System.out.println("before:"+"AroundInterceptor"); } @Override public String intercept(ActionInvocation invocation) { // TODO Auto-generated method stub before(invocation); String result = invocation.invoke(); after(invocation); return result; } @Override public void after(ActionInvocation invocation) { // TODO Auto-generated method stub System.out.println("after:"+"AroundInterceptor"); }}
ExceptionInterceptor拦截器
package com.cmh.intercept;import com.cmh.service.ActionInvocation;public class ExceptionInterceptor implements Interceptor{ @Override public void before(ActionInvocation invocation) { // TODO Auto-generated method stub System.out.println("before:"+"ExceptionInterceptor"); } @Override public String intercept(ActionInvocation invocation) { // TODO Auto-generated method stub before(invocation); String result = invocation.invoke(); after(invocation); return result; } @Override public void after(ActionInvocation invocation) { // TODO Auto-generated method stub System.out.println("after:"+"ExceptionInterceptor"); }}
I18NInterceptor拦截器
package com.cmh.intercept;import com.cmh.service.ActionInvocation;public class I18NInterceptor implements Interceptor{ @Override public void before(ActionInvocation invocation) { // TODO Auto-generated method stub System.out.println("before:"+"I18NInterceptor"); } @Override public String intercept(ActionInvocation invocation) { // TODO Auto-generated method stub before(invocation); String result = invocation.invoke(); after(invocation); return result; } @Override public void after(ActionInvocation invocation) { // TODO Auto-generated method stub System.out.println("after:"+"I18NInterceptor"); }}
调度器实现类DefaultActionInvoation
package com.cmh.service;import java.util.ArrayList;import java.util.List;import com.cmh.action.Action;import com.cmh.intercept.Interceptor;public class DefaultActionInvoation implements ActionInvocation{ int index = 0; private Action action; private List<Interceptor> interceptors = new ArrayList<Interceptor>(); /** * Get action * @return Action the action */ public Action getAction() { return action; } /** * Set action * @param action Action the action to set */ public void setAction(Action action) { this.action = action; } /** * Set interceptors * @param interceptors List<Interceptor> the interceptors to set */ public void addInterceptor(Interceptor interceptors) { this.interceptors.add(interceptors); } @Override public String invoke() {//递归调用 // TODO Auto-generated method stub String result = ""; if(index == interceptors.size()){ result = action.execute(); }else{ Interceptor interceptor =interceptors.get(index); index++; result = interceptor.intercept(this); } return result; }}
测试类
public static void test3(){ Interceptor exptionInterceptor = new ExceptionInterceptor(); Interceptor i18nInterceptor = new I18NInterceptor(); Interceptor aroundInterceptor = new AroundInterceptor(); DefaultActionInvoation actionInvocation = new DefaultActionInvoation(); actionInvocation.addInterceptor(exptionInterceptor); actionInvocation.addInterceptor(i18nInterceptor); actionInvocation.addInterceptor(aroundInterceptor); Action action = new HelloWorldAction(); actionInvocation.setAction(action); String result = actionInvocation.invoke(); System.out.println("Action result:" + result); }
测试结果
由以上代码不难看出,当我们的请求来到时,首先会经DefaultActionInvoation 的invoke处理,调用的次序依次为
ExceptionInterceptor->I18NInterceptor->AroundInterceptor->AroundInterceptor->I18NInterceptor->ExceptionInterceptor
最后才将我们的结果给弄出来,以上为一个拦截器最基本的原理。下面我们来看看struts2中的原代码及流程
strtus2的流程图
我们再来看看他的源代码
以下是DefaultActionInvoation 中的invoke的源代码
/** * @throws ConfigurationException If no result can be found with the returned code */ public String invoke() throws Exception { String profileKey = "invoke: "; try { UtilTimerStack.push(profileKey); if (executed) { throw new IllegalStateException("Action has already executed"); } // 依次调用拦截器堆栈中的拦截器代码执行 if (interceptors.hasNext()) { final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next(); UtilTimerStack.profile("interceptor: "+interceptor.getName(), new UtilTimerStack.ProfilingBlock<String>() { public String doProfiling() throws Exception { // 将ActionInvocation作为参数,调用interceptor中的intercept方法执行 resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); return null; } }); } else { resultCode = invokeActionOnly(); } // this is needed because the result will be executed, then control will return to the Interceptor, which will // return above and flow through again if (!executed) { // 执行PreResultListener if (preResultListeners != null) { for (Iterator iterator = preResultListeners.iterator(); iterator.hasNext();) { PreResultListener listener = (PreResultListener) iterator.next(); String _profileKey="preResultListener: "; try { UtilTimerStack.push(_profileKey); listener.beforeResult(this, resultCode); } finally { UtilTimerStack.pop(_profileKey); } } } // now execute the result, if we're supposed to // action与interceptor执行完毕,执行Result if (proxy.getExecuteResult()) { executeResult(); } executed = true; } return resultCode; } finally { UtilTimerStack.pop(profileKey); } }
拦截器的源代码
public String intercept(ActionInvocation invocation) throws Exception { String result = null; before(invocation); // 调用下一个拦截器,如果拦截器不存在,则执行Action result = invocation.invoke(); after(invocation, result); return result; }
struts的拦截器最大归功于他的动态代理模式,因为我们的action具体类都是一个继承动态代理的类。所以这就不必为每一个类都加相应的逻辑,只需继承就行了。
- java 设计模式 拦截器
- [设计模式]拦截器模式
- 责任链设计模式(过滤器/拦截器)
- Java拦截过滤器模式
- Java拦截过滤器模式
- 责任链设计模式(过滤器、拦截器)
- 责任链设计模式(过滤器、拦截器)
- 设计模式学习笔记--拦截过滤器模式
- 设计模式(30)--拦截过滤器模式
- 设计模式【拦截过滤器模式InterceptingFileterPattern】
- 拦截器模式
- 23种设计模式之——责任链模式(okhttp 拦截器)
- java设计模式--装饰器设计模式(javaIO设计使用)
- Java 装饰器设计模式
- java设计模式:装饰器模式[Decorator]
- java设计模式:装饰器模式[Decorator]
- java设计模式---装饰器模式
- java设计模式---装饰器模式
- Linux ubuntu 基础操作(2)
- ANDROID编程规范与常用技巧
- 分割大文件
- 【MVC】AngularJs+KendoUI开发报表Demo(导出Excel和折线图)
- intellij IDEA快捷键(Windows环境下)
- java 设计模式 拦截器
- 新闻的离线下载功能仿网易之(一) 基本功能实现
- swustoj(翻煎饼)
- tws设置在图标上显示新闻
- CSDN加载图片的问题
- java 基础
- 基于线性回归预测房价
- ScrollView 组件原生事件onScroll
- ActiveMQ-5.9.0 安装和启动