我正在使用自定义拦截器创建新的数据库连接,并在执行操作之前将此连接设置为当前操作。之后,拦截器关闭连接。
我正在寻找一种方便的方法来与操作使用的其他类/静态方法(例如模型)共享此数据库连接。例如,我可以调用静态方法,如User.get( id )
或User.getEmail( id )
,而不必分别将db连接传递给每个方法。
我可以通过执行以下操作将数据库连接设置为来自拦截器的ActionContext
:
ServletActionContext.getActionContext().put("db", db );
然后我可以从静态方法访问此数据库连接,例如:
public class User implements Model
{
public static String getEmail(int id)
{
Connection db =
(Connection) ServletActionContext.getActionContext().get("db");
//...
}
}
我的问题是,是否会为每个给定的请求生成一个新的ActionContext
,所以我可以确定每次都会使用一个新的数据库连接?例如,如果我有500人访问mysite.com/fooAction
,我是否可以确定这500个请求中的每一个都生成一个唯一的ActionContext,并且每次调用User.getEmail()
都只能访问给定的db连接请求?
感谢。
答案 0 :(得分:3)
回答这个问题:
是的。是的。参考是java-doc。它与Alfredo Osorio提供的类似,仅指2.3.x版本。我的问题是,是否会为每个给定的人生成一个新的ActionContext 请求,所以我可以确保每个都使用一个新的数据库连接 时间?
你能说出正在使用的struts2版本吗?
我无法找到任何使用
的版本ServletActionContext.getActionContext()
但是签名是
ServletActionContext.getActionContext(javax.servlet.http.HttpServletRequest)
回答有关线程本地静态的comment,并且每个请求的ActionContext实例仍然是唯一的,因为执行
ActionContext.getContext()
在内部调用线程本地实例的get。
actionContext.get()
您可能会发现以下post在这方面很有帮助。
然而,深入研究方法
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);
}
以下是一些其他参考资料(源代码)。
以下帖子也可能有所帮助。
will-a-new-actioncontext-and-valuestack-be-created-for-every-new-action-object
更新2:
想要添加如上所述here(上面的链接1),如果涉及ActionChaining,则使用自己的拦截器堆栈和结果调用该操作。
执行它的线程是相同的。
复制值堆栈和参数。请参阅 - ActionChainResult #execute(ActionInvocation)。
链调用完成后,将重置action-context的状态。 (参见DefaultActionProxy#execute())。
部分信息:虽然在DefaultActionInvocation#init(ActionProxy)中设置了动作调用,但我无法确定它是否或在何处重置。
来源:
答案 1 :(得分:2)
我的问题是,是否会为每个给定的人生成一个新的ActionContext 请求,所以我可以确保每个都使用一个新的数据库连接 时间?
由于ActionContext使用ThreadLocal,因此它是线程安全的。 Struts 2为每个请求创建一个ActionContext,每个请求都有自己的线程。所以,是的,如果您创建一个新连接并将其存储在ActionContext中,则每个线程都将拥有自己的连接。但是我不建议你将连接存储在ActionContext中,因为这会将你联系到Struts 2,这不是一件好事,你的服务也不应该调用特定于web的类,因为它也会联系它们。
ActionContext是执行Action的上下文。每 context基本上是一个动作需要的对象的容器 像会话,参数,语言环境等执行
ActionContext是线程本地的,这意味着存储的值 ActionContext是每个线程唯一的。见 ActionContext.ActionContextThreadLocal类以获取更多信息。该 这样做的好处是您无需担心用户特定的问题 行动背景,你得到它:
ActionContext context = ActionContext.getContext();最后,因为 线程本地使用你不需要担心你的 动作线程安全。
ActionContext 摘录:
public class ActionContext implements Serializable {
static ThreadLocal<ActionContext> actionContext = new ThreadLocal<ActionContext>();
....
}