CDI和EJB如何比较?相互作用?

Tim*_*Tim 103 java ejb cdi java-ee-6

我很难理解两者如何相互作用以及它们之间的界限在哪里.它们是否重叠?他们之间有冗余吗?

我知道有两个注释都有关联,但我无法通过简短的描述找到两者的完整列表.不确定这是否有助于弄清楚它们之间的区别或重叠的位置.

真的只是困惑.我(我认为)合理地理解EJB,我想我很难理解CDI带来的确切内容以及它如何取代或增强EJB已经提供的内容.

Arj*_*jms 186

目前确实有点令人困惑,因为Java EE中现在有多个组件模型.它们是CDI,EJB3JSF Managed Beans.

CDI是这个街区的新生儿.CDI bean功能dependency injection,scoping以及event bus.CDI bean在注射和范围方面是最灵活的.事件总线非常轻巧,非常适合即使是最简单的Web应用程序.除此之外,CDI还公开了一个非常高级的功能portable extensions,它是供应商为Java EE提供额外功能的一种插件机制,可以在所有实现(Glassfish,JBoss AS,Websphere等)上使用. .

EJB3 bean是从旧的遗留EJB2组件模型*进行改进的,并且是Java EE中第一个通过注释成为托管bean的bean.EJB3 Bean有dependency injection,declarative transactions, declarative security,pooling,concurrency control,asynchronous executionremoting.

EJB3 bean中的依赖注入不像CDI bean那样灵活,EJB3 bean没有范围概念.然而,EJB3 bean是事务性,默认情况下汇集**,两块CDI选择了非常好用的东西,在EJB3的域离开.其他提到的项目也不在CDI中.EJB3虽然没有自己的事件总线,但它确实有一种特殊类型的bean用于监听消息; 消息驱动的bean.这可用于从Java Messaging System或具有JCA资源适配器的任何其他系统接收消息.对简单事件使用完整的消息传递比CDI事件总线更重要,EJB3只定义了一个监听器,而不是生成器API.

自从包含JSF以来,JSF Managed Beans就已存在于Java EE中.他们也有特色dependency injectionscoping.JSF Managed Beans引入了声明性范围的概念.最初的范围相当有限,并且在相同版本的Java EE中,EJB3 bean已经可以通过注释声明,JSF Managed Beans仍然必须用XML声明.当前版本的JSF Managed Beans最终也通过注释进行声明,并使用视图范围和创建自定义范围的功能扩展范围.视图范围记住了对同一页面的请求之间的数据,这是JSF Managed Beans的一个独特功能.

除了视图范围之外,Java EE 6中的JSF Managed Beans仍然很少.缺少CDI中的视图范围是不幸的,因为否则CDI将是JSF Managed Beans提供的完美超级集合.更新:在Java EE 7/JSF 2.2中添加了CDI兼容的@ViewScoped,使CDI确实是完美的超级集.更新2:在JSF2.3中,JSF托管bean已被弃用,转而支持CDI托管bean.

对于EJB3和CDI,情况并非如此明确.EJB3组件模型和API提供了许多CDI不提供的服务,因此通常不能用CDI替换EJB3.另一方面,CDI可以与EJB3结合使用 - 例如向EJB添加范围支持.

专注于CanDI的CDI实现的专家组成员和实现者Reza Rahman经常暗示,与EJB3组件模型相关的服务可以作为一组CDI注释进行改进.如果发生这种情况,Java EE中的所有托管bean都可能成为CDI bean.这并不意味着EJB3消失或变得过时,只是它的功能将通过CDI而不是通过EJB自己的注释(如@Stateless和@EJB)公开.

更新

TomEE和OpenEJB成名的David Blevins在他的博客上很好地解释了CDI和EJB之间的差异和相似之处:CDI,何时打破EJB

*虽然它只是版本号的增量,但EJB3 bean在很大程度上是一种完全不同的bean:通过应用简单的单个注释成为"托管bean"的简单pojo,而EJB2中的模型则是重量级的每个bean都需要过于冗长的XML部署描述符,此外还需要实现各种非常重量级的bean以及大多数无意义的组​​件接口.

**无状态会话bean通常是池化的,有状态会话bean通常不会(但它们可以).对于这两种类型,池化因此是可选的,并且EJB规范不以任何方式强制它.

  • 这是因为可能有些令人困惑的概念,实际上*实际上并不是"CDI bean",但是有些服务应用于托管bean.为了讨论起见,人们(以及我自己)因此将它们称为"CDI bean".在CDI之前,EJB bean没有明确的范围.正如David解释的那样,Stateful隐式地是任何范围(因此没有特别的范围).现在有了CDI,EJB bean可以利用CDI提供的范围.没有CDI规范,所以当单独查看EJB规范时,没有明确的范围. (5认同)
  • 我对你的陈述有点困惑,"EJB3 bean没有范围界定的概念","EJB3没有自己的事件总线".如何与[David Blevin](http://blog.dblevins.com/2012/11/cdi-when-to-break-out-ejbs.html)声称"EJB******CDI bean"相符合因此具有CDI的所有好处"?在你写答案和大卫写博客条目之间,这方面有什么变化吗? (3认同)
  • @Chris要从EJB规范的角度进一步澄清,我们从CDI的开始就做出了刻意的决定,要求EJB实现必须支持100%的EJB上的CDI功能集.CDI的每个方面都适用于EJB,但范围除外,我们不得不将其限制为有状态bean. (3认同)

Max*_*xym 48

CDI - 它是关于依赖注入.这意味着您可以在任何地方注入接口实现.这个对象可以是任何东西,它可以与EJB无关.以下是如何使用CDI注入随机生成器的示例.EJB没有任何内容.当您想要注入非EJB服务,不同的实现或算法时,您将使用CDI(因此您根本不需要EJB).
您理解的EJB,可能您对@EJB注释感到困惑 - 它允许您将实现注入您的服务或其他任何内容.主要思想是注入的类应该由EJB容器管理.似乎CDI确实理解EJB是什么,因此在Java EE 6兼容服务器中,您可以在servlet中同时编写这两者

@EJB EJBService ejbService;
Run Code Online (Sandbox Code Playgroud)

@Inject EJBService ejbService;
Run Code Online (Sandbox Code Playgroud)

这可能会让你感到困惑,但这可能是EJB和CDI之间唯一的桥梁.

当我们讨论CDI时,您可以将其他对象注入CDI托管类(它们应该由CDI感知框架创建).

CDI还提供了什么......例如,你使用Struts 2作为MVC框架(只是示例),你在这里受到限制,即使使用EJB 3.1 - 你不能在Struts动作中使用@EJB注释,它不受管理容器.但是当你添加Struts2-CDI插件时,你可以在那里写@Inject注释同样的东西(所以不需要更多的JNDI查找).这样可以增强EJB的功能.但正如我之前提到的,你注入了CDI - 它与EJB是否相关并不重要,这就是它的力量

PS.更新了示例的链接