Java Struts 2中的ActionContext对于当前请求是唯一的吗?

Java Struts 2中的ActionContext对于当前请求是唯一的吗?,java,servlets,struts2,thread-local,actioncontext,Java,Servlets,Struts2,Thread Local,Actioncontext,我正在使用一个自定义拦截器,它创建一个新的db连接,并在执行操作之前将此连接设置到当前操作。之后,拦截器关闭连接 我正在寻找一种方便的方法来与操作使用的其他类/静态方法(例如模型)共享此db连接。例如,我可以调用静态方法,比如User.get(id)或User.getEmail(id),而无需将db连接分别传递给每个方法 我可以通过执行以下操作,从拦截器将db连接设置到ActionContext: ServletActionContext.getActionContext().put(“db”,

我正在使用一个自定义拦截器,它创建一个新的db连接,并在执行操作之前将此连接设置到当前操作。之后,拦截器关闭连接

我正在寻找一种方便的方法来与操作使用的其他类/静态方法(例如模型)共享此db连接。例如,我可以调用静态方法,比如
User.get(id)
User.getEmail(id)
,而无需将db连接分别传递给每个方法

我可以通过执行以下操作,从拦截器将db连接设置到
ActionContext

ServletActionContext.getActionContext().put(“db”,db)

然后我可以通过静态方法访问此db连接,例如:

public class User implements Model
{ 
   public static String getEmail(int id)
   {
      Connection db = 
         (Connection) ServletActionContext.getActionContext().get("db");
      //...
   }
}
我的问题是,是否会为每个给定的请求生成一个新的
ActionContext
,这样我就可以确保每次都会使用一个新的db连接?例如,如果有500人访问
mysite.com/fooAction
,我是否可以确保这500个请求中的每一个都会生成一个唯一的ActionContext,并且对
User.getEmail()
的每次调用都只会访问给定请求所特有的db连接

谢谢

我的问题是,是否会为每个给定对象生成一个新的ActionContext 请求,因此我可以确保每次都会使用一个新的db连接 时间

因为ActionContext使用ThreadLocal,所以它是线程安全的。Struts 2为每个请求创建一个ActionContext,每个请求都有自己的线程。因此,是的,如果您创建一个新连接并将其存储在ActionContext中,那么每个线程都将有自己的连接。但我不建议您将连接存储在ActionContext中,因为这会将您与Struts 2结合起来,这不是一件好事,而且您的服务不应该调用特定于web的类,因为它也会将它们结合起来

ActionContext是执行操作的上下文。每个 上下文基本上是动作所需对象的容器 执行,如会话、参数、区域设置等

ActionContext是线程本地的,这意味着存储在 每个线程的ActionContext都是唯一的。见 ActionContext.ActionContextThreadLocal类以获取更多信息。这个 这样做的好处是,您不必担心特定于用户的问题 动作上下文,您只需获得它:

ActionContext=ActionContext.getContext();最后,因为 对于线程的本地使用,您无需担心 操作线程安全

ActionContext摘录:

public class ActionContext implements Serializable {

    static ThreadLocal<ActionContext> actionContext = new ThreadLocal<ActionContext>();
    ....
}
公共类ActionContext实现了可序列化{
静态ThreadLocal actionContext=new ThreadLocal();
....
}
我的问题是,是否会为每个给定对象生成一个新的ActionContext 请求,因此我可以确保每次都会使用一个新的db连接 时间

因为ActionContext使用ThreadLocal,所以它是线程安全的。Struts 2为每个请求创建一个ActionContext,每个请求都有自己的线程。因此,是的,如果您创建一个新连接并将其存储在ActionContext中,那么每个线程都将有自己的连接。但我不建议您将连接存储在ActionContext中,因为这会将您与Struts 2结合起来,这不是一件好事,而且您的服务不应该调用特定于web的类,因为它也会将它们结合起来

ActionContext是执行操作的上下文。每个 上下文基本上是动作所需对象的容器 执行,如会话、参数、区域设置等

ActionContext是线程本地的,这意味着存储在 每个线程的ActionContext都是唯一的。见 ActionContext.ActionContextThreadLocal类以获取更多信息。这个 这样做的好处是,您不必担心特定于用户的问题 动作上下文,您只需获得它:

ActionContext=ActionContext.getContext();最后,因为 对于线程的本地使用,您无需担心 操作线程安全

ActionContext摘录:

public class ActionContext implements Serializable {

    static ThreadLocal<ActionContext> actionContext = new ThreadLocal<ActionContext>();
    ....
}
公共类ActionContext实现了可序列化{
静态ThreadLocal actionContext=new ThreadLocal();
....
}

回答问题:

我的问题是,是否会为每个给定对象生成一个新的ActionContext 请求,因此我可以确保每次都会使用一个新的db连接 时间

是的。参考是最重要的。它与提供的类似,只是它指的是2.3.x版本

你能说出struts2的版本是什么吗

我找不到任何使用

ServletActionContext.getActionContext()
但是签名是

ServletActionContext.getActionContext(javax.servlet.http.HttpServletRequest)
回答以下问题:本地线程是静态的,ActionContext实例在每个请求中都是唯一的,因为

ActionContext.getContext()
在内部调用线程本地实例上的get

 actionContext.get()
您可能会发现以下内容在这方面有所帮助

然而,要深入研究,该方法

ServletActionContext.getActionContext(javax.servlet.http.HttpServletRequest)
采用与使用本地线程不同的路由

public static ActionContext getActionContext(HttpServletRequest req) {
    ValueStack vs = getValueStack(req);
    if (vs != null) {
        return new ActionContext(vs.getContext());
    } else {
        return null;
    }
}

public static ValueStack getValueStack(HttpServletRequest req) {
    return (ValueStack) req.getAttribute(STRUTS_VALUESTACK_KEY);
}

下面是一些附加参考(源代码)

以下帖子也可能会有所帮助

  • 更新2:

    如前所述,希望添加(上面的链接1),在涉及的情况下,将使用自己的拦截器堆栈和结果调用该操作

    然而,执行它的线程是相同的

    将复制值堆栈和参数。请参阅-ActionChainResult#execute(ActionInvocation)

    链调用完成后,将重置操作上下文的状态。(请参见DefaultActionProxy#execute()

    部分信息:虽然操作调用是在DefaultActionInvocation#init(ActionProxy)中设置的,但我无法确定是否重置或在何处重置

    资料来源: