gpt4 book ai didi

jakarta-ee - 整合EJB(JNDI)和CDI的最佳方式

转载 作者:行者123 更新时间:2023-12-05 03:01:27 25 4
gpt4 key购买 nike

目前我们有一个部署架构,其中一堆面向数据的服务通过 RMI 暴露给业务服务。两种类型(面向数据的服务和业务服务)都是无状态 session bean。每个数据服务接口(interface)包(包含远程接口(interface))也有一个定位器,用于执行 JNDI 查找。这样我们就可以从业务服务逻辑中的任何地方调用面向数据的服务。

这是定位器的样子:

public final class OMRLocator {

private static final Logger LOG = Logger.getLogger( OMRLocator.class );

private static final String ORG_WILDFLY_INITIAL_CTX_FACTORY = "org.wildfly.naming.client.WildFlyInitialContextFactory";

private OMRLocator() {
}

@Produces
public static OrganisationsAndMandatesRegister locate() {
try {
Properties ctxProp = new Properties();
ctxProp.put( Context.INITIAL_CONTEXT_FACTORY, ORG_WILDFLY_INITIAL_CTX_FACTORY );
InitialContext ctx = new InitialContext( ctxProp );
return (OrganisationsAndMandatesRegister) ctx.lookup( OrganisationsAndMandatesConstants.REMOTE_NAME );
}
catch ( NamingException ex ) {
LOG.log( Level.WARN, "Cannot reach: " + OrganisationsAndMandatesConstants.REMOTE_NAME, ex );
return null;
}
}
}

我们在 JBOSS EAP6 上运行并开始试验 CDI。因此,我们向数据服务 beans 和 @Produces 添加了一个 beans.xml 以使(在本例中为 OrganisationAndMandatesRegister CDI 可注入(inject). 这个想法是, future 我们可能会重新打包我们的应用程序,并将数据服务与业务服务一起打包在一个企业文件中。

最近我们迁移到 JBOSS EAP7.2(Wildfly 8?),突然间我们看到了各种意想不到的延迟和事务问题。

我怀疑我们获取 bean 的方式是造成这些问题的一个因素。例如:我猜范围取决于业务 EJB 生命周期,但是对于业务服务中的 locate() 的每次调用都会生成一个新的数据服务实例。

那么:使用 CDI 时生成远程 bean(通过 RMI)的最佳方法是什么?鉴于这两种类型的服务都是无状态的(或者这是自动完成的),我是否应该考虑范围界定?

最佳答案

如果在生产者方法上没有定义范围,则使用@Dependend,因此找到合适的范围,可能是@RequestScoped。当您从 JNDI 检索 EJB 时,您不会获得新的实例,而是从池中获得一个实例,该实例在多次调用中可能是相同的。您的问题可能是 EJB 拦截器,因为如果依赖作用域,EJB 实例在注入(inject)后始终相同,并且永远不会释放。

摆脱@Produces,因为CDI 与EJB 集成并且EJB 可以通过@Inject 或@EJB 注入(inject)。如果您想保留 Locator 类,那么您可以在其中注入(inject) EJB 并返回正确的 EJB 实例(实际上是一个代理),其中 Locator 应该是@ApplicationScoped。另一种方法是使用允许编程查找的实例。使用 Object 类型,您可以访问容器的所有 CDI Bean(包括 EJB),因此通用接口(interface)将有助于最大限度地减少可访问的 bean。

请参阅以下链接以获得更多帮助。

https://docs.jboss.org/weld/reference/latest/en-US/html/injection.html#_obtaining_a_contextual_instance_by_programmatic_lookup

Inject a stateless EJB with @Inject into CDI Weld ManagedBean (JSF 1.2 EJB Application on jboss 6 AS)

http://www.adam-bien.com/roller/abien/entry/inject_vs_ejb


总结一下:

选项 a) 保持原样。也许使用 @Dependent 明确范围以指示这是在调用 bean 创建时调用的(注入(inject)调用 bean 的构造函数)

选项 b) 使用无状态 @ApplicationScoped session bean

@LocalBean // otherwise @EJB will not work
@ApplicationScoped // this instance should be created only once per ear
public class OMRLocator {

@EJB // does implicitly a remote (default) JNDI lookup
private OrganisationsAndMandatesRegister instance;

@Produces
@Dependent // just to make it explicit
public OrganisationsAndMandatesRegister locate() {
return instance;
}
}

关于jakarta-ee - 整合EJB(JNDI)和CDI的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55721688/

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