接触struts2后,用得最频繁的是struts2的拦截器.
看了下struts2源码,为了便于理解是如何调用多个拦截器(拦截器链),简化了几个接口,做个小结.
想更加深入了解具体细节可以参考xwork2和struts2源代码.
1.Action接口以及实现
描叙用户一个Action行为
public interface Action {
public String execute();
}
简单Action实现
public class MyAction implements Action{
private final static String SUCCESS = "success";
public String execute() {
System.out.println("execute a action.....");
return SUCCESS;
}
}
2.拦截器接口以及实现
直接从struts2拿过来了
public interface Interceptor {
//拦截方法
public String intercept(ActionInvocation invocation);
}
拦截器的两个简单实现
public class TypeOneInterceptor implements Interceptor {
public String intercept(ActionInvocation invocation) {
System.out.println("interceptor one at "+ new java.util.Date());
return invocation.invoke();
}
}
public class TypeTwoInterceptor implements Interceptor {
public String intercept(ActionInvocation invocation) {
System.out.println("interceptor two at "+new java.util.Date());
return invocation.invoke();
}
}
3.重要的ActionInvocation接口以及实现
ActionInvocation接口描叙了一个Action的执行状态,持有拦截器和Action.
public interface ActionInvocation {
Object getAction(); //关联的Action
String invoke(); //调用拦截器或者Action
String invokeActionOnly(); //直接调用Action
String getResultCode(); //result code
void setResultCode(String resultCode);
}
可以认为ActionInvocation是个粘合剂,把Action和拦截器粘合了在一起.
简单的ActionInvocation实现
public class DefaultActionInvocation implements ActionInvocation {
public Iterator<Interceptor> intercepts;
public String resultCode;
protected Object action;
public String invoke() {
if(intercepts.hasNext()){//有拦截器
Interceptor interceptor = intercepts.next();
resultCode = interceptor.intercept(DefaultActionInvocation.this);//执行拦截方法
}
else
resultCode=invokeActionOnly();//调用action
return resultCode;
}
public String invokeActionOnly(){
String result = null;;
try{
Method method = getAction().getClass().getMethod("execute");
return (String)method.invoke(getAction(), null);
}
catch(Exception e){
e.printStackTrace();
}
return result;
}
// resultCode,action,intercepts的setter/getter}
4.客户端调用
Action action = new MyAction(); //action实例
List<Interceptor> list = new ArrayList<Interceptor>(); //拦截器
list.add(new TypeTwoInterceptor());
list.add(new TypeOneInterceptor());
Iterator<Interceptor> intercepts = list.iterator();
DefaultActionInvocation invocation = new DefaultActionInvocation();
invocation.setAction(action);//设入Action
invocation.setIntercepts(intercepts);//设入拦截器
System.out.println(invocation.invoke());//执行Action,有拦截器则调用拦截器
5小结
通过struts2的这种设计,把action和intercepter很好的解耦,达到了设计上的灵活性.
再通过配置文件来设置拦截器,方便了用户的定制 .
ps:开源项目aopalliance(spring aop基于此框架)中,MethodInterceptor,MethodInvocation与struts2中的Interceptor,ActionInvocation 结构和作用仿佛.是否是种设计模式?
ps:查了些资料,发现与责任链模式比较类似,以后再好好研究 :)