gpt4 book ai didi

java - 启动 CDI 对话并将 @ConversationScoped bean 注入(inject)无状态 session bean

转载 作者:行者123 更新时间:2023-11-29 08:31:41 36 4
gpt4 key购买 nike

有人问过类似的问题,但没有完全解决我想做的事情。我们有一个基于 Seam 2.x 的旧应用程序,它带有我们正在转换为 CDI 的批处理作业框架。作业框架使用 Seam 上下文对象来发起对话。作业框架还加载一个特定于作业的数据持有者(基本上是一个 Map),然后可以通过 Seam Contexts 对象访问链下的任何服务,包括来自 SLSB 的数据持有者。其中一些服务可以更新 map ,以便作业状态可以更改并在记录之间进行检测。

看起来在 CDI 中,作业将 @Inject 一个 CDI 对话对象,并手动开始/结束对话。我们还将定义一个新的 ConversationScoped bean 来保存 Map (MapBean)。我不清楚的是两件事:

首先,作业还需要@Inject MapBean,以便它可以在调用 Conversation.begin() 方法之前加载特定于作业的数据。容器会知道将此实例传递给调用链中的服务吗?

相关的,根据这个问题Is it possible to @Inject a @RequestScoped bean into a @Stateless EJB?应该可以将 ConservationScoped bean 注入(inject)到 SLSB 中,但这似乎有点神奇。如果 SLSB 被不同的进程(作业、UI 调用等)使用,它是否会为每个调用获得单独的实例?

为澄清和简化类结构而进行的编辑:

MapBean 需要是一个 ConversationScoped 对象,包含作业的特定实例/运行的数据。

@ConversationScoped
public class MapBean implements Serializable {
private Map<String, Object> data;
// accessors
public Object getData(String key) {
return data.get(key);
}
public void setData(String key, Object value) {
data.put(key, value);
}

}

作业将是ConversationScoped:

@ConversationScoped
public class BatchJob {
@Inject private MapBean mapBean;
@Inject private Conversation conversation;
@Inject private JobProcessingBean jobProcessingBean;
public void runJob() {
try {
conversation.begin();
mapBean.setData("key", "value"); // is this MapBean instance now bound to the conversation?
jobProcessingBean.doWork();
} catch (Exception e) {
// catch something
} finally {
conversation.end();
}
}
}

作业可能会调用 SLSB,并且 MapBean 的当前对话范围实例需要可用:

@Stateless
public class JobProcessingBean {
@Inject private MapBean mapBean;

public void doWork() {
// when this is called, is "mapBean" the current conversation instance?
Object value = mapBean.getData("key");
}
}

我们的工作和 SLSB 框架非常复杂,SLSB 可以调用许多其他服务或本地实例化的业务逻辑类,并且每一个都需要访问对话范围的 MapBean

最佳答案

First, the job needs to also @Inject the MapBean so that it can be loaded with job-specific data before the Conversation.begin() method is called. Would the container know to pass this instance to services down the call chain?

是的,因为 MapBean@ConversationScoped它在从 conversation.begin() 开始的持续时间内与调用链相关联直到 conversation.end() .你可以想到@ConversationScoped (以及 @RequestScoped@SessionScoped )作为 ThreadLocal 中的实例- 虽然每个线程都存在它们的一个实例,但每个实例都绑定(bind)到该单个线程。

Related to that, according to this question Is it possible to @Inject a @RequestScoped bean into a @Stateless EJB? it should be possible to inject a @ConservationScoped bean into a SLSB, but it seems a bit magical. If the SLSB is used by a different process (job, UI call, etc), does it get separate instance for each call?

如果你看到这个模式和我上面解释的一样,那就没有你想象的那么神奇了。 SLSB 确实获得了一个单独的实例,但不仅仅是任何实例,该实例属于调用 SLSB 的范围。

除了您发布的链接外,另请参阅 this answer .

我测试了与您发布的代码类似的代码,它按预期工作 - MapBean在整个通话过程中注入(inject)的是同一个。请注意两件事:

  • BatchJob也是@ConversationScoped但不执行 Serializable ,这将不允许 bean 钝化。
  • data未初始化,因此您将在 runJob() 中获得 NPE .

关于java - 启动 CDI 对话并将 @ConversationScoped bean 注入(inject)无状态 session bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47518334/

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