您的位置:首页 > 编程语言 > Java开发

struts2核心与拦截器的原理解析

2013-05-12 22:57 591 查看
一.拦截器的实现原理:不夸张的说,你懂了拦截器的实现原理,就懂了strut2的核心实现原理

当用户发出一个请求的时候,会被strut2的核心控制器拦截:

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

这个类的方法大致如下:

1. 读取strut2的配置文件,我估计可能是使用dom4j第三方实现的类库来读取配置文件,

2. 通过反射的机制创建这个action代理的实例(动态代理)

3. 创建一个ActionInvocation实例,将拦截器的引用和action的代理对象传递给ActionInvocation实例。

4. ActionInvocation实例将调用invoke()的方法,其实就是一个递归。。。

源代码如下:
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();
String interceptorMsg = "interceptor: " + interceptor.getName();
UtilTimerStack.push(interceptorMsg);
try {
resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
}
finally {
UtilTimerStack.pop(interceptorMsg);
}
} 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) {
if (preResultListeners != null) {
for (Object preResultListener : preResultListeners) {
PreResultListener listener = (PreResultListener) preResultListener;

String _profileKey = "preResultListener: ";
try {
UtilTimerStack.push(_profileKey);
listener.beforeResult(this, resultCode);
}
finally {
UtilTimerStack.pop(_profileKey);
}
}
}

// now execute the result, if we're supposed to
if (proxy.getExecuteResult()) {
executeResult();
}

executed = true;
}

return resultCode;
}
finally {
UtilTimerStack.pop(profileKey);
}
}


准确的说:

Action A{

Iinterceptor A = new Interceptor();

}

为了降低两者之间的耦合,则通过注入的方法,从而达到了 "高内聚,低耦合!"

拦截器中调用invoke的方法返回结果之后,先修改结果是没有用的。因为这个时候已经将结果视图发送到了客户端。
public String intercept(ActionInvocation actionInvocation) throws Exception {

ActionContext ac = ActionContext.getContext();
User user = (User)ac.getSession().get("user");
System.out.println(user.getName()+"---------------");

Action action = (Action)actionInvocation.getAction();
if(action instanceof UserAware){
((UserAware) action).setUser(user);
}
System.out.println(name+"开始执行");
String result =  actionInvocation.invoke();
//这样的修改是没有什么意义的
result = action.LOGIN;
System.out.println(name+"完成执行");
return result;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: