CDI和EJB如何比较? 相互作用?
我很难理解这两者之间的相互作用以及它们之间的界限在哪里。 他们重叠? 他们之间是否有冗余?
我知道有两个相关的注释,但我一直没能find一个完整的清单,简要说明。 不知道这是否有助于清除它们之间的差异或重叠。
真的只是困惑。 我认为我相当了解EJB,我想我很难理解CDI究竟带来了什么,以及它如何取代或增强EJB已经提供的东西。
CDI – 这是关于dependency injection。 这意味着你可以在任何地方注入接口实现。 这个对象可以是任何东西,它可以与EJB无关。 这里是一个如何使用CDI注入随机生成器的例子。 没有关于EJB的东西。 当你想注入非EJB服务,不同的实现或algorithm(因此你根本不需要EJB)时,你将会使用CDI。
你确实理解的EJB,可能你被@EJB注解弄糊涂了 – 它允许你将实现注入到你的服务或其他任何东西中。 主要的想法是,你注入的类应该由EJB容器来pipe理。 似乎CDI确实了解EJB是什么,所以在符合Java EE 6的服务器中,在您的servlet中,您可以同时写入两者
@EJB EJBService ejbService;
和
@Inject EJBService ejbService;
这可能会让你感到困惑,但这可能是EJB和CDI之间唯一的桥梁。
当我们谈论CDI时,可以将其他对象注入CDI托pipe类(它们应该由CDI知晓的框架创build)。
还有什么CDI提供的……比如说,你使用Struts 2作为MVC框架(只是例子),而且在这里也是有限的,即使使用EJB 3.1 – 你也不能在Struts action中使用@EJB注解,容器。 但是当你添加Struts2-CDI插件的时候,你可以在那里写入@Inject注解来做同样的事情(所以不需要更多的JNDI查找)。 这样它增强了EJB的能力。 但正如我之前提到的那样,你用CDI注入的东西 – 与EJB是否相关并不重要,这就是它的力量
PS。 更新了示例的链接
目前确实有点混乱,因为现在Java EE中有多个组件模型。 他们是CDI , EJB3和JSF托pipe豆 。
CDI是这个街区上的新人。 CDI beanfunctiondependency injection
, scoping
和event bus
。 CDI豆在注射和范围方面是最灵活的。 事件总线非常轻便,非常适合即使是最简单的Web应用程序。 除此之外,CDI还公开了一个非常先进的function,称为portable extensions
( portable extensions
,这是供应商为Java EE提供额外function的一种插件机制,可以在所有实现上提供(GlassFish,JBoss AS,Websphere,等等)。
EJB3 bean是从旧的传统EJB2组件模型*改造而来的,并且是Java EE中第一批通过注释来pipe理bean的bean。 EJB3 beanfunctiondependency injection
, declarative transactions
, declarative security
, pooling
, concurrency control
, asynchronous execution
和remoting
。
EJB3 bean中的dependency injection不像在CDI bean中那么灵活,EJB3 bean没有概念范围。 但是,EJB3 bean是事务性的,默认情况下是池化的,这是CDIselect留在EJB3领域的两个非常有用的东西。 其他提到的项目在CDI中也不可用。 虽然EJB3没有自己的事件总线,但它有一个特殊types的bean来监听消息; 消息驱动的bean。 这可用于从Java消息系统或具有JCA资源适配器的任何其他系统接收消息。 对于简单的事件使用完整的消息传递比CDI事件总线重要得多,而EJB3只定义了一个监听器,而不是一个生产者API。
自从JSF被包括在内之后, JSF Managed Beans已经存在于Java EE中。 它们也具有dependency injection
和scoping
。 JSF Managed Beans引入了声明范围的概念。 最初的范围相当有限,在同一版本的Java EE中EJB3 bean已经可以通过注释来声明,JSF Managed Beans仍然必须用XML声明。 当前版本的JSF Managed Beans也最终通过注释来声明,范围扩展为视图范围和创build自定义范围的能力。 视图范围可以logging到同一页面的请求之间的数据,这是JSF Managed Beans的一个独特function。
除了视图范围之外,Java EE 6中的JSF Managed Beans还很less.CDI中缺less的视图范围是不幸的,因为否则CDI将成为JSF Managed Bean提供的完美超集。 更新 :在Java EE 7 / JSF 2.2中添加了一个兼容CDI的@ViewScoped ,使得CDI确实是一个完美的超集。
使用EJB3和CDI的情况并不是那么明显。 EJB3组件模型和API提供了很多CDI不提供的服务,所以通常EJB3不能被CDI替代。 另一方面,CDI可以与EJB3结合使用 – 例如,向EJB添加范围支持。
Reza Rahman,一个名为CanDI的CDI实现的专家组成员和实现者,经常暗示与EJB3组件模型相关的服务可以作为一组CDI注释来改进。 如果发生这种情况,Java EE中的所有托pipebean都可能成为CDI bean。 这并不意味着EJB3消失或者已经过时,而只是它的function将通过CDI而不是通过EJB自己的注释(如@Stateless和@EJB)来公开。
更新
TomEE和OpenEJB的大名鼎鼎的David Blevins在他的博客上很好地解释了CDI和EJB之间的差异和相似之处: CDI,何时打破EJB
*虽然这只是版本号的增量,但是EJB3 bean大部分是一种完全不同的bean:一个简单的pojo,通过应用一个简单的单个注释,成为一个“受pipe理的bean”,而EJB2中的一个重量级和除了需要实现各种非常重量级和大部分无意义的组件接口所需的bean以外,每个bean都需要过度冗长的XML部署描述符。
**无状态会话bean通常是合并的,有状态会话bean通常不会(但它们可以)。 对于这两种types,pooling是可选的,EJB规范并没有强制要求。