java – 使用EJBContext getContextData – 这是安全吗?

前端之家收集整理的这篇文章主要介绍了java – 使用EJBContext getContextData – 这是安全吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我计划使用EJBContext从应用程序层(特别是消息驱动的bean)传递一些不能直接注入或传递参数( 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映射内容只对当前的调用/线程可见吗?换句话说,如果两个线程同时运行回调方法,并且都从JNDI中查找一个EJBContext,它们实际上会得到不同的contextData映射内容

而且,这是如何实际工作的 – EJBontext从JNDI查找返回真的是一个围绕ThreadLocal的结构的包装对象?

解决方法

我认为一般来说,该方法的合同是使得拦截器webservice上下文和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的情况感兴趣的是,Webservice连接更容易在源中发现.

猜你在找的Java相关文章