struts2 拦截器堆栈是由一个ActionInvocation的东东递归调用执行的过程,
在堆栈的底部是由action,PreResultListener,Result组成的东东。
/**
* @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);
}
}
/**
* @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);
}
}
从源码中,我们可以看到,我们之前提到的Struts2的Action层的4个不同的层次,在这个方法中都有体现,他们分别是:拦截器(Interceptor)、Action、PreResultListener和Result。在这个方法中,保证了这些层次的有序调用和执行。由此我们也可以看出Struts2在Action层次设计上的众多考虑,每个层次都具备了高度的扩展性和插入点,使得程序员可以在任何喜欢的层次加入自己的实现机制改变Action的行为。
在这里,需要特别强调的,是其中拦截器部分的执行调用:
resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
表面上,它只是执行了拦截器中的intercept方法,如果我们结合拦截器来看,就能看出点端倪来:
public String intercept(ActionInvocation invocation) throws Exception {
String result = null;
before(invocation);
// 调用invocation的invoke()方法,在这里形成了递归调用
result = invocation.invoke();
after(invocation, result);
return result;
}
原来在intercept()方法又对ActionInvocation的invoke()方法进行递归调用,ActionInvocation循环嵌套在intercept()中,一直到语句result = invocation.invoke()执行结束。这样,Interceptor又会按照刚开始执行的逆向顺序依次执行结束。
分享到:
相关推荐
Struts2拦截器原理分析实例 博文链接:https://zmx.iteye.com/blog/457432
在action执行之前先进行拦截器的拦截处理,然后再执行action的execute方法,返回给拦截器,再对应相应result
仿struts 2 拦截器原理
二、实现Struts2拦截器原理 Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的 拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器 三...
struts2拦截器原理模拟,示例里面做了大量注释,对所有可能让你产生疑惑的地方都详细描述了原因。
浅谈Struts2拦截器的原理与实现.docx
Struts2拦截器的实现原理(csdn)————程序
struts2拦截器,里面介绍了struts2拦截器的执行的原理,用了非常生动的例子讲解了struts2执行过程。
struts2拦截器的教程,可以深入学习struts2的原理
struts2工作原理及拦截器和过滤器
里面是自己实现struts拦截器的一个原理,基于jdk的动态代理
参考博文:http://blog.csdn.net/u011638419/article/details/41592837
该文档详细描述了struts2中拦截器的原理及使用方法,内含实现简单登录模块的拦截器代码。
参考博文:http://blog.csdn.net/u011638419/article/details/41510483
7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。 8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果...
myeclipse平台下使用struts2.3框架搭建实例,理解struts2工作原理,了解struts2自定义类型转换,自定义拦截器,掌握struts2的mvc框架应用
本PPT描述了Struts中拦截器的讲解,通过本PPT读者可以掌握Struts的拦截器的工作原理,还可以学会使用拦截器
拦截器是一种AOP(面向切面编程)思想的编程方式.它提供一种机制是开发者能够把相对独立的代码抽离出来,...下面这篇文章主要给大家介绍了关于Struts2拦截器Interceptor的原理与配置的相关资料,需要的朋友可以参考下。