已经提出了类似的问题,但并没有完全解决我想要做的事情。我们有一个旧的基于 Seam 2.x 的应用程序,带有一个我们正在转换为 CDI 的批处理作业框架。作业框架使用 Seam Contexts 对象来启动对话。作业框架还加载了一个特定于作业的数据持有者(基本上是一个地图),然后可以通过 Seam Contexts 对象由链下的任何服务访问,包括来自 SLSB。其中一些服务可以更新地图,以便作业状态可以更改并从记录到记录进行检测。
看起来在 CDI 中,作业将@Inject
是一个 CDI 对话对象,并手动开始/结束对话。我们还将定义一个ConversationScoped
包含 Map ( MapBean
) 的新 bean。我不清楚的是两件事:
首先,作业还需要@InjectMapBean
以便在调用 Conversation.begin() 方法之前加载作业特定的数据。容器是否知道将此实例传递给调用链中的服务?
与此相关,根据这个问题Is it possible to @Inject a @RequestScoped bean into a @Stateless EJB? 应该可以将ConservationScoped
bean 注入到 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
.