gpt4 book ai didi

jakarta-ee - 在哪里使用 EJB 3.1 和 CDI?

转载 作者:行者123 更新时间:2023-12-03 04:37:34 27 4
gpt4 key购买 nike

我正在制作一个基于 Java EE 的产品,我在其中使用了 GlassFish 3 和 EJB 3.1。

我的申请有 session beans ,调度程序并使用网络服务。我最近才知道Apache TomEE , 支持 Contexts and Dependency Injection (CDI) . GlassFish 容器还支持 CDI。

我可以替换不需要 CDI 还没有提供的任何功能的 session bean 吗?如果那样的话,我可以获得什么好处?

最佳答案

是的,您可以自由地混合 CDI 和 EJB 并获得一些不错的结果。听起来您正在使用 @WebService@Schedule ,这是将 EJB 添加到组合中的充分理由。

那里有很多困惑,所以这里有一些关于 EJB 和 CDI 的一般信息,因为它们相互关联。

EJB >= CDI

请注意,EJB CDI bean 因而具有 CDI 的所有优点。反过来不是这样(还)。所以绝对不要养成思考“EJB vs CDI”的习惯,因为这种逻辑实际上转化为“EJB+CDI vs CDI”,这是一个奇怪的等式。

在 Java EE 的 future 版本中,我们将继续调整它们。对齐的意思是允许人们做他们已经可以做的事情,只是没有 @Stateful , @Stateless@Singleton注释在顶部。

实现条款中的 EJB 和 CDI

最终,EJB 和 CDI 共享相同的代理组件基本设计。当您获得对 EJB 或 CDI bean 的引用时,它不是真正的 bean。相反,您得到的对象是假的(代理)。当你在这个假对象上调用一个方法时,调用会转到容器,容器将通过拦截器、装饰器等发送调用,并处理任何事务或安全检查。完成所有这些后,调用最终会转到真实对象,结果通过代理传回给调用者。

区别仅在于如何解析要调用的对象。 “已解决”只是指容器在何处以及如何查找要调用的真实实例。

在 CDI 中,容器查看“范围”,它基本上是一个存在特定时间段的哈希图(每个请求 @RequestScoped,每个 HTTP session @SessionScoped,每个应用程序 @ApplicationScoped,JSF 对话 @ConversationScoped ,或根据您的自定义范围实现)。

在 EJB 中,如果 bean 的类型为 @Stateful,容器也会查看哈希图。 .安 @Stateful bean 还可以使用任何上述范围注释,使其与范围内的所有其他 bean 一起生存和消亡。在 EJB @Stateful本质上是“任何范围的”bean。 @Stateless基本上是一个实例池——您在一次调用期间从池中获取一个实例。 @Singleton本质上是 @ApplicationScoped
因此,从根本上讲,您可以用“EJB”bean 做的任何事情都应该可以用“CDI”bean 做。在封面下,很难将它们区分开来。除了如何解析实例之外,所有管道都是相同的。

就容器在执行此代理时将提供的服务而言,它们目前并不相同,但正如我所说,我们正在 Java EE 规范级别进行处理。

性能说明

忽略您可能拥有的任何“轻”或“重”心理图像。这就是营销。它们大部分具有相同的内部设计。 CDI 实例解析可能稍微复杂一些,因为它稍微更加动态和上下文。相比之下,EJB 实例解析相当静态、愚蠢和简单。

我可以从 TomEE 的实现角度告诉您,调用 EJB 与调用 CDI bean 之间的性能差异几乎为零。

默认为 POJO,然后是 CDI,然后是 EJB

当然,在没有好处的情况下不要使用 CDI 或 EJB。当您开始需要注入(inject)、事件、拦截器、装饰器、生命周期跟踪和类似的东西时,请使用 CDI。大部分时间都是这样。

除了这些基础知识之外,还有许多有用的容器服务,只有在通过添加 @Stateful 使 CDI bean 也成为 EJB 时,您才可以选择使用。 , @Stateless , 或 @Singleton就可以了。

这是我何时拆分 EJB 的简短列表。

使用 JAX-WS

暴露 JAX-WS @WebService .我很懒。当@WebService也是一个EJB,您不必在web.xml 中列出它并将其映射为servlet。文件。这对我来说是工作。另外,我可以选择使用下面提到的任何其他功能。所以这对我来说是不费吹灰之力的。

可联系 @Stateless@Singleton只有。

使用 JAX-RS

通过 @Path 公开 JAX-RS 资源.我还是很懒。当 RESTful 服务也是 EJB 时,您再次获得自动发现,而不必将其添加到 JAX-RS Application子类或类似的东西。另外,我可以公开与 @WebService 完全相同的 bean如果我想或使用下面提到的任何强大的功能。

可联系 @Stateless@Singleton只有。

启动逻辑

通过 @Startup 在启动时加载.目前在 CDI 中没有与此等效的内容。不知何故,我们错过了添加类似 AfterStartup 的内容。容器生命周期中的事件。如果我们这样做了,您就可以拥有 @ApplicationScoped bean 监听它并且实际上与 @Singleton 相同与 @Startup .它在 CDI 1.1 的列表中。

可联系 @Singleton只有。

并行工作
@Asynchronous方法调用。在任何服务器端环境中启动线程都是禁忌。线程过多是一个严重的性能杀手。这个注解允许你使用容器的线程池并行化你所做的事情。这太棒了。

可联系 @Stateful , @Stateless@Singleton .

安排工作
@ScheduleScheduleExpression基本上是一个 cron 或 Quartz功能。也非常棒。大多数容器只是在封面下使用 Quartz 来实现这一点。然而,大多数人不知道,Java EE 中的调度工作是事务性的!如果您更新数据库然后安排一些工作并且其中一个失败,则两者都会自动清理。如果EntityManager持久调用失败或刷新出现问题,无需取消调度工作。是的,交易。

可联系 @Stateless@Singleton只有。

在 JTA 事务中使用 EntityManager

以上关于交易的说明当然需要您使用 JTA托管 EntityManager .您可以将它们与普通的“CDI”一起使用,但是如果没有容器管理的事务,它会变得非常单调,重复 UserTransaction提交/回滚逻辑。

适用于所有 Java EE 组件,包括 CDI、JSF @ManagedBean , @WebServlet , @WebListener , @WebFilter@TransactionAttribute但是,注释可用于 @Stateful , @Stateless@Singleton只有。

保持 JTA 管理 EntityManagerEXTENDED托管 EntityManager允许您保留 EntityManager之间开放 JTA交易而不会丢失缓存的数据。适合时间和地点的好功能。负责任地使用:)

可联系 @Stateful只有。

轻松同步

当您需要同步时,@Lock(READ)@Lock(WRITE)注释非常好。它允许您免费获得并发访问管理。跳过所有 ReentrantReadWriteLock 管道。在同一个桶中是 @AccessTimeout ,它允许你说一个线程在放弃之前应该等待多长时间才能访问 bean 实例。

可联系 @Singleton只有 bean 类。

关于jakarta-ee - 在哪里使用 EJB 3.1 和 CDI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13487987/

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