发表时间:2008-11-17
最后修改:2008-11-20
Dispatcher类
Dispatcher类是在struts2中定义的,在 webwork2 中叫DispatcherUtils,
作用相同:
1 初始化模块参数,
2 将 xwork 于 web层分离,
3 中转请求,进入xwork 的 action处理流程。
1 初始化,涉及方法 init()
在上一篇的 FilterDispatcher中的init() 方法,有这么两句:
- dispatcher = createDispatcher(filterConfig);
- dispatcher.init();
就是调用Dispatcher的初始化。
2 xwork 定义了一个类 : ActonContext,
ActonContext 有两个作用
1) 线程安全,
过这个类,xwork2 实现了 action 的线程安全,
为每一次的action请求, 分配一个独立的ActonContext。
2) 于 web 层分离,
xwork的做法,是把web层中组件中的变量
(主要是javax.servlet包中的类,如HttpServletRequest)
取出来,放入ActonContext。
这样xwork就不要在向外访问web层了。
涉及方法
- public Map<String,Object> createContextMap(HttpServletRequest request, HttpServletResponse response,
- ActionMapping mapping, ServletContext context) {
Dispatcher 的这个方法,把web层的参数取出然后放入Map 中,(以备xwork构造ActionContext)。
3 中转请求,调action处理逻辑,这个是比较重要的一个地方,
- public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
- ActionMapping mapping) throws ServletException {
-
- Map<String, Object> extraContext = createContextMap(request, response, mapping, context);
-
-
- ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
- if (stack != null) {
- extraContext.put(ActionContext.VALUE_STACK, ValueStackFactory.getFactory().createValueStack(stack));
- }
-
- String timerKey = "Handling request from Dispatcher";
- try {
- UtilTimerStack.push(timerKey);
- String namespace = mapping.getNamespace();
- String name = mapping.getName();
- String method = mapping.getMethod();
-
- Configuration config = configurationManager.getConfiguration();
- ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
- namespace, name, extraContext, true, false);
- proxy.setMethod(method);
- request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
-
-
- if (mapping.getResult() != null) {
- Result result = mapping.getResult();
- result.execute(proxy.getInvocation());
- } else {
- proxy.execute();
- }
-
-
- if (stack != null) {
- request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
- }
- } catch (ConfigurationException e) {
- LOG.error("Could not find action or result", e);
- sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
- } catch (Exception e) {
- throw new ServletException(e);
- } finally {
- UtilTimerStack.pop(timerKey);
- }
- }
Configuration config = configurationManager.getConfiguration();
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, extraContext, true, false);
得到框架的配置信息,得到框架的Container,构造出 ActionProxy。
这个过程中,涉及到几个xwork较核心的类,Configuration, ConfigurationManager, Container,
Configuration, ConfigurationManager 负责框架配置信息初始化的类
- public class DefaultConfiguration implements Configuration {
-
- protected static final Logger LOG = LoggerFactory.getLogger(DefaultConfiguration.class);
-
-
-
- protected Map<String, PackageConfig> packageContexts = new LinkedHashMap<String, PackageConfig>();
- protected RuntimeConfiguration runtimeConfiguration;
- protected Container container;
- protected String defaultFrameworkBeanName;
- protected Set<String> loadedFileNames = new TreeSet<String>();
-
-
- ObjectFactory objectFactory;
这是描述框架总体配置信息的,其中,
Map<String, PackageConfig> 放的是package的config,对应struts2 配置文件中 package标签内容,
PackageConfig
- public class PackageConfig extends Located implements Comparable, Serializable, InterceptorLocator {
-
- private static final Logger LOG = LoggerFactory.getLogger(PackageConfig.class);
-
- private Map<String, ActionConfig> actionConfigs;
- private Map<String, ResultConfig> globalResultConfigs;
- private Map<String, Object> interceptorConfigs;
- private Map<String, ResultTypeConfig> resultTypeConfigs;
- private List<ExceptionMappingConfig> globalExceptionMappingConfigs;
- private List<PackageConfig> parents;
- private String defaultInterceptorRef;
- private String defaultActionRef;
- private String defaultResultType;
- private String defaultClassRef;
- private String name;
- private String namespace = "";
- private boolean isAbstract = false;
- private boolean needsRefresh;
里边是一些package的信息,其中Map<String, ActionConfig> 放的就是action的描述类ActionConfig了
ActionConfig
- public class ActionConfig extends Located implements Serializable {
-
- public static final String WILDCARD = "*";
-
- protected List<InterceptorMapping> interceptors;
- protected Map<String, String> params;
- protected Map<String, ResultConfig> results;
- protected List<ExceptionMappingConfig> exceptionMappings;
- protected String className;
- protected String methodName;
- protected String packageName;
- protected String name;
- protected Set<String> allowedMethods;
其中
interceptors : action的拦截器,
results: action执行后用来收尾的,如,跳到定义好的页面。
className 类名,packageName 包名,methodName 默认是 execute。
框架一般有个必须要做的活,就是把某配置文件的信息读到框架系统中来,
xwork2中,XMLConfigurationProvider 就是干这个的,
他读xml配置文件(就是我们定义action的配置的那个文件),
然后把这些信息写到Configuration中。
ConfigurationManager 则负责调用适当的 ConfigurationProvider,
执行初始化逻辑,和返回具体的Configuration。
初始化等前期工作完毕后,则开始执行action的逻辑了,
xwork 使用了代理模式执行action,
proxy.execute();
从这一句起, strust2 就把工作交接给了xwork了。