`
milan_1982
  • 浏览: 2016 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

PrepareOperations中的createActionContext

 
阅读更多
//ValueStack是接口,其默认实现类是OgnlValueStack
//OgnlValueStack里面有两个重要的属性:
//CompoundRoot root
//transient Map<String, Object> context;

//而context又是一个OgnlContext,OgnlContext也有两个重要的属性:
//private Object _root;
//private Map _values = new HashMap(23);


package org.apache.struts2.dispatcher.ng;

PrepareOperations类中:
    public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
        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) {

            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;
    }

   
    //一句一句来看
   
   
   
    ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();

   
    //dispatcher.getContainer().getInstance(ValueStackFactory.class)这部分还不是太懂,
    //根据字面估计一下就是创建ValueStackFactory的实例。
    //ValueStackFactory是接口,其默认实现是OgnlValueStackFactory
    //调用OgnlValueStackFactory的createValueStack():
   
   
    public ValueStack createValueStack() {
    	  //ValueStack是接口,其默认实现类是OgnlValueStack,所以实际上是new一个OgnlValueStack出来。
        ValueStack stack = new OgnlValueStack(xworkConverter, compoundRootAccessor, textProvider, allowStaticMethodAccess);
        container.inject(stack);
        //把容器加入OgnlValueStack.context,实际是加入到OgnlContext的context中。
        stack.getContext().put(ActionContext.CONTAINER, container);
        return stack;
    }

   
   
   
    //OgnlValueStack的构造方法
    protected OgnlValueStack(XWorkConverter xworkConverter, CompoundRootAccessor accessor, TextProvider prov, boolean allowStaticAccess) {
    	  //new一个CompoundRoot出来
        setRoot(xworkConverter, accessor, new CompoundRoot(), allowStaticAccess);
        push(prov);
    }

   
       
       
    protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot,
                           boolean allowStaticMethodAccess) {
        //OgnlValueStack.root = compoundRoot;             	 
        this.root = compoundRoot;
        //方法/属性访问策略。
        this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess);
        //创建context了,创建context使用的是ongl的默认方式。
        //Ognl.createDefaultContext返回一个OgnlContext类型的实例
        //这个OgnlContext里面,root是OgnlValueStack中的compoundRoot,map是OgnlContext自己创建的private Map _values = new HashMap(23);
        this.context = Ognl.createDefaultContext(this.root, accessor, new OgnlTypeConverterWrapper(xworkConverter), securityMemberAccess);  
        
                      
        //不是太理解,猜测如下:
        //context是刚刚创建的OgnlContext,其中的HashMap类型_values加入如下k-v:
        //key:com.opensymphony.xwork2.util.ValueStack.ValueStack
        //value:this,这个应该是当前的OgnlValueStack实例。
        //刚刚用断点跟了一下,_values里面是:
        //com.opensymphony.xwork2.ActionContext.container=com.opensymphony.xwork2.inject.ContainerImpl@96231e
        //com.opensymphony.xwork2.util.ValueStack.ValueStack=com.opensymphony.xwork2.ognl.OgnlValueStack@4d912
        context.put(VALUE_STACK, this);
        //此时:OgnlValueStack中的compoundRoot是空的;
        //context是一个OgnlContext,其中的_root指向OgnlValueStack中的root,_values里面的东西,如刚才所述。
        //OgnlContext中的额外设置。
        Ognl.setClassResolver(context, accessor);
        ((OgnlContext) context).setTraceEvaluations(false);
        ((OgnlContext) context).setKeepLastEvaluation(false);
    }        
        

       
    //以下方法源自:package ognl;
    public static Map createDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess )
    {
    	  //new一个OgnlContext出来。
    	  //此时返回的OgnlContext类型,root,map已经被初始化,为空,另外还有一些工具类。
        return addDefaultContext( root, classResolver, converter, memberAccess, new OgnlContext() );
    }
    
    //对new出来的OgnlContext做一些初始化工作,包括:
    //root赋值给OgnlContext中的 private Object _root;
    
    //OgnlContext中的Map,就是维护上下文环境中的数据,new出来的时候已经被初始化:private Map _values = new HashMap(23);
    //另外初始化时会传入一些工具类,如果没有传入,使用默认的。
    //此时返回的OgnlContext类型,root,map已经被初始化,为空,另外还有一些工具类。
    public static Map addDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess, Map context )
    {
        OgnlContext     result;
        
        if (!(context instanceof OgnlContext)) {
            result = new OgnlContext();
            result.setValues(context);
        } else {
            result = (OgnlContext)context;
        }
        
        
        if (classResolver != null) {
            result.setClassResolver(classResolver);
        }
        if (converter != null) {
            result.setTypeConverter(converter);
        }
        if (memberAccess != null) {
            result.setMemberAccess(memberAccess);
        }
        result.setRoot(root);
        return result;
    }        
            

   
    //OgnlContext中的_root,指向OgnlValueStack中的root  
    public void setRoot(Object value)
    {
        _root = value;
        _accessorStack.clear();
        _typeStack.clear();
        _currentObject = value;

        if (_currentObject != null)
        {
            setCurrentType(_currentObject.getClass());
        }
    }       
       
       
       
       
       

   
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics