如何将数据从EJB Interceptor传递到Async EJB中的Interceptor

时间:2014-07-17 16:45:53

标签: java java-ee asynchronous ejb

我有2个无状态EJB StatelessA和StatelessB,它们都分别有拦截器InterceptorA和InterceptorB。此外,StatelessB具有异步方法。像这样:

@Stateless
@Interceptors(InterceptorA.class)
public class StatelessA{...

@Stateless
@Asynchronous
@Interceptors(InterceptorB.class)
public class StatelessB{...

在StatelessA上调用方法时,它会调用多个StatelessB方法并返回一个值。 我正在尝试开发2个拦截器来存储StatelessB调用的总时间和小计时间,这是拦截器的目标。

我需要这样做,所以InterceptorA可以看到InterceptorB数据的细节,所以我只在DB中存储一个值,包含总时间(SLSB A)和小计时间(SLSB B)。

我尝试使用ThreadLocal变量(包含一些时间列表,如long []),如果StatelessB不是异步的话,它可以正常工作。 问题是,当它是异步的时,变量不可用,因为它在不同的线程(AFAIK)中运行。

我也尝试过注入EJBContext或使用InvocationContext,但没有一个能够正常工作。

有人能指出我还有其他选择吗? 提前谢谢。

3 个答案:

答案 0 :(得分:1)

我一遍又一遍地思考这个问题,并找到了一个使用安全上下文传递数据的解决方案。 该解决方案涉及使用在异步调用中传播的唯一数据,如EJB 3.1中所指定的那样:

  

4.5.4安全性调用方安全主体通过异步方法调用进行传播。来电安全主要传播   异步方法调用的行为与它完全相同   用于同步会话bean调用。

在JBoss中,可以访问安全上下文并使用其中的数据映射将值从InterceptorA传递给InterceptorB,如下所示:

在InterceptorA中:

SecurityContext securityContext = SecurityContextAssociation.getSecurityContext();
securityContext.getData().put("interceptorAData",data);

在InterceptorB中:

SecurityContext securityContext = SecurityContextAssociation.getSecurityContext();
securityContext.getData().get("interceptorAData");

我对它进行了测试,它在JBoss EAP 6.1中运行良好。

此解决方案意味着将拦截器连接到服务器实现(JBoss AS),但该原则适用于其他服务器。 优点是它将应用程序逻辑与拦截器分离,这是第一个目标。 我感谢任何评论。

答案 1 :(得分:0)

是否可以将所需信息存储在@Entity对象中,然后使用@PersistenceContext批注将EntityManager注入bean中以保留并查找数据?类似的东西:

@PersistenceContext
EntityManager entityManager;
...
method() {
MyEntityTimer met = new MyEntityTimer(getCurrentTime(), id);
entityManager.persist(met);
}
...
elsewhere:
MyEntityTimer met = entityManager.find(MyEntityTimer.class, id);

@Entity
@Table(name = "TABLE")
public class MyEntityTimer {

@Id
@Column(name = "ID")
private int id;
...
}

答案 2 :(得分:0)

我会用我最后做的回答我的问题。 我发现将一个变量从拦截器A传递给拦截器B的唯一方法是向EJB A和B添加一个参数,如下所示:

@Stateless
@Interceptors(InterceptorA.class)
public class StatelessA{
public void methodA(Object reserved, ...other params )

@Stateless
@Asynchronous
@Interceptors(InterceptorB.class)
public class StatelessB{
public void methodB(Object reserved, ...other params)

这样,当调用InterceptorA时,我将使用我需要与InterceptorB共享的数据设置保留参数。 InterceptorB将访问此变量,而不会从参数中获取它。

这个解决方案的缺点是需要伪参数,以某种方式将EJB与拦截器耦合..