凡使用EJB 3.1和CDI?(Where to use EJB 3.1 and CDI?)

2019-06-21 06:13发布

我正在在我使用的是基于Java EE产品的GlassFish 3和EJB 3.1。

我的应用程序会话bean ,调度和使用Web服务。 最近,我了解的Apache TomEE ,支持上下文和依赖注入(CDI) 。 Glassfish的容器也支持CDI。

我能代替会话Bean,我不要求CDI也尚不提供任何功能? 如果那么,什么是我能得到什么好处?

Answer 1:

是的,你可以自由搭配既CDI和EJB并取得一些伟大的成绩。 这听起来像你正在使用@WebService@Schedule ,这是很好的理由将EJB的组合。

有很多困惑摆在那里,所以这里是EJB和CDI的一般信息,因为它们涉及到每一个在一起。

EJB> = CDI

请注意,EJB CDI豆,因此具有CDI的所有优点。 相反的是不正确的(还)。 所以,绝对不要以为“EJB VS CDI”的习惯为逻辑真的转化为“EJB + CDI VS CDI”,这是一个奇怪的等式。

在Java EE的未来版本中,我们将继续进行对齐。 什么整合机构是让人们做他们已经可以做什么,只是没有@Stateful@Stateless@Singleton顶部注释。

EJB和CDI的实施条款

最终,EJB和CDI分享的是代理的组件相同的基本设计。 当你到一个EJB或CDI bean的引用,它是不是真正的豆。 而是你给予的对象是假的(代理)。 当你这个假对象上调用一个方法,然后将呼叫转到谁将会通过拦截器,装饰等发送呼叫以及采取任何交易或安全检查的护理容器。 一旦所有做到这一点,呼叫终于进入到真正的对象和结果通过代理给调用者传回。

所不同的只是在谈到如何调用该对象得到解决。 通过“解决”我们只是意味着,在那里和容器如何寻找真正的实例调用。

在CDI的容器会在“范围”,这将主要是对生活的特定时间段(每个请求一个HashMap @RequestScoped ,每个HTTP会话@SessionScoped ,每个应用程序@ApplicationScoped ,JSF会话@ConversationScoped ,或者按您的自定义的范围执行)。

在EJB容器看起来也成为一个HashMap如果Bean是类型@Stateful 。 一个@Stateful豆也可以使用任何上述范围注释导致其生活和在范围内的所有其他豆类死亡。 在EJB @Stateful基本上是“任何作用域”豆。 该@Stateless基本上是一个实例池-你从池中的一个调用期间获得一个实例。 该@Singleton基本上@ApplicationScoped

因此,在最基本的层面,任何你可以用“EJB”豆你应该能够以“CDI”豆做。 根据覆盖它是非常难区分它们。 所有的管道是的情况下,是如何解决的例外相同。

他们不是目前在服务这样做代理时,容器会提供的条件是相同的,但正如我说我们在的Java EE规范级别上工作。

性能注

忽略你可能有任何“轻”或“重”的精神图像。 这是所有营销。 他们大部分相同的内部设计。 CDI实例解析也许是更复杂一点,因为它是稍微更具活力和语境。 EJB实例分辨率是相当静态的,愚蠢的,简单的比较。

我可以从TomEE实现的角度来看告诉你,有一个调用EJB VS调用CDI豆约零的性能差异。

默认的POJO,然后CDI,然后EJB

当然,当没有好处不使用CDI或EJB。 扔在CDI当你开始想要注射,事件,拦截器,装饰,生命周期跟踪之类的东西。 这是大部分的时间。

除了这些基本知识,有许多有用的容器服务,您只需如果你让你CDI豆也是一个EJB通过增加使用的选项@Stateful@Stateless@Singleton就可以了。

下面是当我打破了EJB的短名单。

使用JAX-WS

露出了JAX-WS @WebService 。 我很懒。 当@WebService也是一个EJB,你不必列出它并把它映射作为一个servlet web.xml文件。 这是工作给我。 另外,我得选择使用任何的下文提到的其他功能。 所以这是一个没有脑子我。

可供@Stateless@Singleton只。

使用JAX-RS

暴露通过JAX-RS资源@Path 。 我还懒。 当RESTful服务也是一个EJB,再次你会得到自动发现,并没有将它添加到JAX-RS Application子类或类似的东西。 另外,我可以公开完全相同的bean作为一个@WebService如果我想或使用任何的下文提到的强大功能。

可供@Stateless@Singleton只。

启动逻辑

通过在启动时加载@Startup 。 目前尚没有相当于这CDI。 不知怎的,我们错过了添加类似的AfterStartup容器生命周期事件。 如果我们这样做了,你根本就已经有一个@ApplicationScoped豆是听了它,这将有效地同为@Singleton@Startup 。 这是名单CDI 1.1。

提供给@Singleton只。

并行工作

@Asynchronous方法调用。 启动线程是一个没有没有任何服务器端环境。 有太多的线程是一个严重的性能杀手。 该注释允许您并行你使用容器的线程池的东西。 这太棒了。

可供@Stateful@Stateless@Singleton

调度工作

@ScheduleScheduleExpression基本上cron或Quartz功能。 也很真棒。 大多数容器只使用石英盖此之下。 大多数人不知道,不过,在Java EE该调度工作是事务性的! 如果更新,然后数据库安排一些工作,他们中的一个发生故障,都将自动清理。 如果EntityManager持续调用失败或有冲洗一个问题,有没有必要取消计划的工作。 耶,交易。

可供@Stateless@Singleton只。

一个JTA事务中使用EntityManagers

在课程的交易上面注意需要你使用JTA管理EntityManager 。 你可以用简单的“CDI”使用它们,但没有容器管理事务也可以得到真正单调复制UserTransaction提交/回滚逻辑。

适用于所有的Java EE组件,包括CDI,JSF @ManagedBean@WebServlet@WebListener@WebFilter@TransactionAttribute注解,然而,是提供给@Stateful@Stateless@Singleton只。

保持JTA管理EntityManager

EXTENDED管理EntityManager可以让你保持一个EntityManager之间的开放JTA事务,而不是失去缓存的数据。 在正确的时间和地点很好的功能。 使用负责任:)

可用来@Stateful只。

轻松同步

当你需要同步时, @Lock(READ)@Lock(WRITE)注解是相当出色的。 它可以让你得到的并发访问管理是免费的。 跳过所有的ReentrantReadWriteLock管道。 在同一个桶是@AccessTimeout ,它允许你说一个线程应该等待多长时间放弃之前可以访问bean实例。

提供给@Singleton只豆。



Answer 2:

如果你真的不使用任何的EJB 3.1的功能,答案很简单。 但你猜你questiion表明你怀疑有EJB 3.1 conceptes你从没有意识到他们的获益。 一个例子是,容器可以保持SLSB准备的池来使用,从而使JMS和数据库连接不要有注入作为请求部分



文章来源: Where to use EJB 3.1 and CDI?