gpt4 book ai didi

java - 使用 EJBContext getContextData - 这安全吗?

转载 作者:搜寻专家 更新时间:2023-10-30 21:04:57 25 4
gpt4 key购买 nike

我计划使用 EJBContext 将一些属性从应用程序层(特别是消息驱动的 bean)传递到无法直接注入(inject)或传递参数的持久性生命周期回调( session 监听器)在 EclipseLink、实体生命周期回调等中),并且该回调通过 JNDI 获取 EJBContext

这似乎可行,但是否存在任何隐藏的问题,如我遗漏的线程安全或对象生命周期? (假设传递的属性值是不可变的,如 String 或 Long。)

示例 bean 代码

@MessageDriven
public class MDB implements MessageListener {
private @Resource MessageDrivenContext context;

public void onMessage(Message m) {
context.getContextData().put("property", "value");
}
}

然后是消费 EJBContext 的回调

public void callback() { 
InitialContext ic = new InitialContext();
EJBContext context = (EJBContext) ic.lookup("java:comp/EJBContext");
String value = (String) context.getContextData().get("property");
}

我想知道的是,我能否确定 contextData 映射内容仅对当前调用/线程可见?换句话说,如果两个线程同时运行 callback 方法,并且都从 JNDI 中查找 EJBContext,它们实际上会得到不同的 contextData map 内容?

而且,这实际上是如何工作的 - 从 JNDI 查找返回的 EJBContext 最终真的是围绕类似 ThreadLocal 的结构的包装对象吗?

最佳答案

我认为一般来说,方法的契约是启用拦截器 + web 服务上下文和 bean 之间的通信。因此上下文应该对所有代码可用,只要没有创建新的调用上下文。因此,它应该是绝对线程安全的。

EJB 3.1 规范的第 12.6 节说明如下:

The InvocationContext object provides metadata that enables interceptor methods to control the behavior of the invocation chain. The contextual data is not sharable across separate business method invocations or lifecycle callback events. If interceptors are invoked as a result of the invocation on a web service endpoint, the map returned by getContextData will be the JAX-WS MessageContext

此外,getContextData方法在4.3.3中有描述:

The getContextData method enables a business method, lifecycle callback method, or timeout method to retrieve any interceptor/webservices context associated with its invocation.

在实际实现上,JBoss AS做了如下工作:

public Map<String, Object> getContextData() {
return CurrentInvocationContext.get().getContextData();
}

CurrentInvocationContext 使用基于 thread-local linked list 的堆栈弹出和推送当前调用上下文。

参见 org.jboss.ejb3.context.CurrentInvocationContext .调用上下文只是懒惰地创建一个简单的 HashMap,就像在 org.jboss.ejb3.interceptor.InvocationContextImpl 中所做的那样。

Glassfish 做了类似的事情。它还gets an invocation , 并且这样做 from an invocation manager ,它也使用基于 thread-local array list 的堆栈再次弹出和推送这些调用上下文。

GlassFish 实现的 JavaDoc 在这里特别有趣:

This TLS variable stores an ArrayList. The ArrayList contains ComponentInvocation objects which represent the stack of invocations on this thread. Accesses to the ArrayList dont need to be synchronized because each thread has its own ArrayList.

就像在 JBoss AS 中一样,GlassFish 也懒得创建一个简单的 HashMap,在本例中为 com.sun.ejb.EjbInvocation . GlassFish 案例中有趣的是 Web 服务连接更容易在源中发现。

关于java - 使用 EJBContext getContextData - 这安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8608349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com