日期:2014-05-19  浏览次数:20667 次

Struts2源码问题--ActionContex的创建
今天在看strust2的源码,有一个问题没法从源码中找到答案:ActionContext是什么时候被创建的?

问题是这样引出来的:我在看ParametersInterceptor拦截器中设置请求参数的方法,发现它是是调用ActionContext的getParameters()方法,在ActionContext中有一个context的Map属性,调用这个Map的get方法,传入相应的参数就能得到parameters、session之类的对象。
但是找不到创建context的地方,这个属性都是在创建ActionContext的时候注入的,请问ActionContext
是哪个类、在什么时候创建的?而真正创建context的代码在哪个类里?

------解决方案--------------------
呵呵 lz我稍微看了下源码 ActionContext的创建是在  
  prepare.createActionContext(request, response);
这个里面有创建  ActionContext 你好好看下这个方法里面的代码:

        ActionContext ctx;
        Integer counter = 1;
        Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
        if (oldCounter != null) {
            counter = oldCounter + 1;
        }
        
        ActionContext oldContext = ActionContext.getContext();
        if (oldContext != null) {
            // detected existing context, so we are probably in a forward
            ctx = new ActionContext(new HashMap<String, Object>(oldContext.getContextMap()));
        } else {
            ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
            stack.getContext().putAll(dispatcher.createContextMap(request, response, null, servletContext));
            ctx = new ActionContext(stack.getContext());
        }
        request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
       ActionContext.setContext(ctx);        return ctx;
    

这里要注意的是
 ActionContext.setContext(ctx);
这个很关键。跟进去会发现  actionContext.set(context);。actionContext对象其实是ThreadLocal对象,然后你会发现你后来取得ActionContenxt的时候都是通过
    public static ActionContext getContext() {
        return (ActionContext) actionContext.get();
呵呵大致懂了吧  把生成的ActionContext对象先放在ThreadLocal对象中等到要用的时候再取出来用。。。。其实不是取出来的原来的而是原来的一个副本具体可以看下ThreadLocal这个类的用法。。。。