Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在异步EJB中将数据从EJB拦截器传递到拦截器_Java_Jakarta Ee_Asynchronous_Ejb - Fatal编程技术网

Java 如何在异步EJB中将数据从EJB拦截器传递到拦截器

Java 如何在异步EJB中将数据从EJB拦截器传递到拦截器,java,jakarta-ee,asynchronous,ejb,Java,Jakarta Ee,Asynchronous,Ejb,我有两个无状态EJB无状态A和无状态B,它们分别有拦截器InterceptorA和InterceptorB。此外,无状态B具有异步方法。大概是这样的: @Stateless @Interceptors(InterceptorA.class) public class StatelessA{... @Stateless @Asynchronous @Interceptors(InterceptorB.class) public class StatelessB{... @Stateless @

我有两个无状态EJB无状态A和无状态B,它们分别有拦截器InterceptorA和InterceptorB。此外,无状态B具有异步方法。大概是这样的:

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

@Stateless
@Asynchronous
@Interceptors(InterceptorB.class)
public class StatelessB{...
@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)
在无状态a上调用方法时,它调用多个无状态B方法并返回一个值。 我试图开发2个拦截器来存储无状态B调用的总时间和小计时间,这是拦截器的目标

我需要这样做,以便InterceptorA可以看到InterceptorB数据的详细信息,因此我只在DB中存储一个值,包含(SLSB a的)总时间和(SLSB B的)小计时间

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

我还尝试注入EJBContext或使用InvocationContext,但都不起作用

有人能告诉我还有什么其他选择吗?
提前感谢。

将您需要的信息存储在@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);
以及:


我将用我最后所做的来回答我的问题。 我发现的将变量从拦截器a传递到拦截器B的唯一方法是向EJB a和B添加一个参数,类似这样:

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

@Stateless
@Asynchronous
@Interceptors(InterceptorB.class)
public class StatelessB{...
@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与拦截器耦合起来。

我反复考虑了这个问题,找到了一个解决方案,它使用安全上下文传递数据。 解决方案涉及使用异步调用中传播的唯一数据,如EJB 3.1中所述:

4.5.4安全性调用方安全主体通过异步方法调用进行传播。呼叫方安全主体传播 异步方法调用的行为与它的行为完全相同 不支持同步会话bean调用

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

在InterceptorA中:

SecurityContext securityContext = SecurityContextAssociation.getSecurityContext();
securityContext.getData().put("interceptorAData",data);
在拦截器中:

SecurityContext securityContext = SecurityContextAssociation.getSecurityContext();
securityContext.getData().get("interceptorAData");
我对它进行了测试,它在JBossEAP6.1中运行得非常好

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

谢谢您的回答:)这可能有效,但我如何将“id”值从拦截器传递到拦截器呢?我不想向bean中的方法添加任何新参数..您能创建一个新的类级别变量并添加一个将id从a传递到B的新方法吗?也许在调用B中的第一个方法之前,先调用B.setId(id)。如果不修改ejb,就不可能将id从A传递到B。我找到了一种向EJB添加参数的方法,为拦截器保留一个变量。我将用这个细节来回答这个问题。无论如何谢谢你!我尝试过这个方法,它对我的特殊情况有效,至少在出现任何陷阱之前。。。然而,我所知道的还没有一个浮出水面。。。所以我不妨给wildfly一个+1检查