//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());
}
}
分享到:
相关推荐
at org.apache.struts2.dispatcher.ng.PrepareOperations.cleanupRequest(PrepareOperations.java:103) at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter...
Struts2 源码分析主要涉及其在Tomcat启动过程中的初始化步骤以及请求处理流程。首先,我们来看Tomcat启动时Struts2框架如何准备和执行。 在Tomcat启动时,Struts2的Filter文件被加载,具体是`...
5. `PrepareOperations`类被实例化,它的主要职责是在每个请求开始时创建`ActionContext`,并在请求结束时清除`ActionContext`。此外,它还负责根据URI查找`ActionConfig`,创建`ActionMapping`。 6. `...
Struts2是一个基于MVC(Model-...开发者需要创建自定义的Action类,该类通常会继承`org.apache.struts2.dispatcher.ng.ExecuteOperations`和`org.apache.struts2.dispatcher.ng.PrepareOperations`接口,或者直接继承`...
MATLAB数字滤波器设计及其在语音信号去噪中的应用:源码详解与报告分享,MATLAB 数字滤波器设计 及其语音信号去噪应用。 (供学习交流)带源码,带注释。 有代码和报告。 ,核心关键词:MATLAB; 数字滤波器设计; 语音信号去噪应用; 源码; 注释; 代码与报告。,"MATLAB数字滤波器设计及其在语音信号去噪中的应用:带源码注释与报告"
COMSOL软件模拟三维电化学腐蚀过程的研究分析,comsol三维电化学腐蚀。 ,核心关键词:Comsol;三维电化学;腐蚀;模型模拟;电化学腐蚀过程。,"Comsol模拟:三维电化学腐蚀过程解析"
基于COMSOL的降雨入渗模型:边坡与渗流边界下的强度折减塑性形变研究,comsol降雨入渗模型,边坡降雨边界与渗流边界 强度折减塑性形变 ,comsol降雨入渗模型; 降雨边界; 渗流边界; 强度折减; 塑性形变,"COMSOL降雨入渗模型:边坡渗流与强度折减塑性形变分析"
2025员工安全意识培训试题及答案.docx
Python自动化办公源码-06在Word表格中将上下行相同内容的单元格自动合并
基于深度学习的神经网络技术在信息通信领域的应用研究.pdf
1.内容概要 通过KNN实现鸢尾花分类,即将新的数据点分配给已知类别中的某一类。该算法的核心思想是通过比较距离来确定最近邻的数据点,然后利用这些邻居的类别信息来决定待分类数据点的类别。 2.KNN算法的伪代码 对未知类别属性的数据集中的每个点依次执行以下操作: (1)计算已知类别数据集中的点与当前点之间的距离; (2)按照距离递增次序排序; (3)选取与当前点距离最小的k个点; (4)确定前k个点所在类别的出现频率; (5)返回前k个点出现频率最高的类别作为当前点的预测分类。 3.数据集说明 代码使用`pandas`库加载了一个名为`iris.arff.csv`的数据集 4.学习到的知识 通过鸢尾花分类学习了KNN算法,选择样本数据集中前k个最相似的数据,就是KNN算法中k的出处。k值过大,会出现分类结果模糊的情况;k值较小,那么预测的标签比较容易受到样本的影响。在实验过程中,不同的k值也会导致分类器的错误率不同。KNN算法精度高、无数据输入的假定,可以免去训练过程。但是对于数据量较多的训练样本,KNN必须保存全部数据集,可能会存在计算的时间复杂度、空间复杂度高的情况,存在维数灾难问
感应电机控制与矢量控制仿真:磁链闭环、转速闭环与电流闭环的综合应用研究,感应电机控制仿真,矢量控制,异步电机仿真,磁链闭环,转速闭环,电流闭环 ,核心关键词:感应电机控制仿真; 矢量控制; 异步电机仿真; 磁链闭环; 转速闭环; 电流闭环,"感应电机矢量控制仿真:磁链、转速、电流三闭环异步电机模拟"
威纶通TK6071IP触摸屏锁屏宏指令程序详解:注释清晰,便于理解与学习,威纶通触摸屏锁屏宏指令程序 ~ 威纶通触摸屏锁屏宏指令程序,TK6071IP触摸屏 利用宏指令程序来控制,宏指令注释清晰,方便理解程序。 具有很好的学习意义和借鉴价值。 ,关键词:威纶通触摸屏;锁屏宏指令程序;TK6071IP触摸屏;宏指令控制;注释清晰;学习借鉴。,威纶通触摸屏宏指令程序:清晰注释,学习借鉴之利器
2025输血相关法律法规试题考核试题及答案.docx
Python游戏编程源码-2048小游戏
2025最新康复医学概论考试题库(含答案).doc
Python自动化办公源码-09用Python批量往Word文档中指定位置添加图片
高品质车载充电器技术解决方案:含原理图、PCB图、C源代码及DSP控制器资料,附赠CDCDC模块资料,车载充电器 3Kw OBC 车载充电器 含原理图、PCB图、C源代码、变压器参数等生产资料。 附赠15kwdcdc模块资料 1、这款产品的方案采用的是dsp2803x系列。 2、原理图和Pcb采用AD绘制。 此方案仅供学习 ,车载充电器; 3Kw OBC; 原理图; PCB图; C源代码; 变压器参数; 生产资料; dsp2803x系列; AD绘制; 15kwdcdc模块资料,3Kw车载充电器方案:DSP2803x系列原理图、PCB图及C源学习包
2025最新康复医学考试题及答案.docx
内容概要:本文介绍了一种用于视频处理的新型卷积神经网络(CNN)加速器。主要创新点在于引入了混合精度计算、跨帧数据重用控制器及引擎,以及混合位宽差帧数据编码解码器。这些特性有效解决了视频帧间的时空相关性和稀疏性带来的挑战,提高了处理速度并降低了功耗和带宽需求。具体来说,通过对连续帧的数据相似度利用,可以在保持高精度的同时减少计算量和内存访问次数;通过多类型稀疏卷积聚类数组实现了对现代稀疏神经网络的支持;并通过混合位宽度编码减少了离芯片外的数据传输量,最高达到68%。 适用人群:从事深度学习硬件加速设计的研究人员和技术爱好者;关注AI边缘计算领域的从业者。 使用场景及目标:适用于自动驾驶汽车摄像头、监控系统等实时视频流应用场景。旨在为开发者提供高效的低能耗解决方案,在有限的时间和资源下完成大量的图像信号处理任务,如跟踪、分类等。 其他说明:文中还详细描述了芯片的设计细节,测试平台构建,以及不同模型(如MobileNet)在网络上的实际性能表现。