CDI 和 EJB 相比如何?相互影响?
我很难理解两者如何相互作用以及它们之间的界限在哪里。它们重叠吗?他们之间有裁员吗?
我知道两者都有相关的注释,但我无法找到两者的完整列表和简短描述。不确定这是否有助于澄清它们的不同之处或重叠之处。
真的只是很困惑。我(认为我)对 EJB 相当了解,我想我很难准确理解 CDI 带来的内容以及它如何取代或增强 EJB 已经提供的功能。
I'm having a tough time understanding how the two interact and where the boundary between them lies. Do they overlap? Are there redundancies between them?
I know there are annotations associated with both, but I haven't been able to find a complete list for both with brief descriptions. Not sure if this would help clear up how they differ or where they overlap.
Really just confused. I (think I) understand EJB reasonably well, I guess I'm having a hard time understanding exactly what CDI brings to the table and how it supplants or enhances what EJB already offers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
目前确实有点令人困惑,因为 Java EE 中有多个组件模型。它们是CDI、EJB3 和JSF Managed Beans。
CDI 是新来的。 CDI bean 具有
依赖注入
、作用域
和事件总线
功能。 CDI bean 在注入和范围界定方面是最灵活的。事件总线非常轻量级,甚至非常适合最简单的 Web 应用程序。除此之外,CDI 还公开了一个非常先进的功能,称为“可移植扩展”,这是一种插件机制,供供应商为 Java EE 提供额外的功能,这些功能可在所有实现上使用( Glassfish、JBoss AS、Websphere 等)。EJB3 bean 是从旧的 EJB2 组件模型* 改造而来的,并且是 Java EE 中第一个通过注释进行管理的 bean。 EJB3 bean 具有
依赖注入
、声明性事务
、声明性安全性
、池化
、并发控制
>、异步执行
和远程处理
。EJB3 bean 中的依赖关系注入不如 CDI bean 灵活,并且 EJB3 bean 没有作用域概念。然而,EJB3 bean 是事务性的并且默认是池化的**,CDI 选择将这两个非常有用的东西留在 EJB3 的领域中。其他提到的项目在 CDI 中也不可用。 EJB3 虽然没有自己的事件总线,但它确实有一种特殊类型的 bean 用于监听消息;消息驱动 bean。这可用于从 Java 消息系统或任何其他具有 JCA 资源适配器的系统接收消息。对简单事件使用完整的消息传递比 CDI 事件总线重量级得多,并且 EJB3 只定义了侦听器,而不是生成器 API。
自从包含 JSF 以来,JSF Managed Beans 就存在于 Java EE 中。它们还具有
依赖注入
和作用域
功能。 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 不提供的服务,因此通常 EJB3 不能被 CDI 替代。另一方面,CDI 可以与 EJB3 结合使用 - 例如,向 EJB 添加范围支持。
Reza Rahman 是专家组成员,也是名为 CanDI 的 CDI 实现的实现者,他经常暗示与 EJB3 组件模型相关的服务可以作为一组 CDI 注释进行改进。如果发生这种情况,Java EE 中的所有托管 bean 都可能成为 CDI bean。这并不意味着 EJB3 消失或过时,只是它的功能将通过 CDI 公开,而不是通过 EJB 自己的注释(如 @Stateless 和 @EJB)公开。
更新
TomEE 和 OpenEJB 出名的 David Blevins 在他的博客上很好地解释了 CDI 和 EJB 之间的区别和相似之处:CDI,何时中断 EJB
*
虽然这只是版本号的增加,但 EJB3 bean 在很大程度上是一种完全不同类型的 bean:一个简单的 pojo,通过应用简单的单个注释成为“托管 bean”,而 EJB2 中的模型则需要重量级且过度的注释。每个 bean 都需要详细的 XML 部署描述符,此外,该 bean 需要实现各种极其重量级且大部分无意义的组件接口。
** 无状态会话 bean 通常是池化的、有状态的会话 Bean 通常不会(但也可以是)。因此,对于这两种类型,池化都是可选的,并且 EJB 规范并未强制要求采用任何一种方式。
It is currently indeed a bit confusing as there are now multiple component models in Java EE. They are CDI, EJB3 and JSF Managed Beans.
CDI is the new kid on the block. CDI beans feature
dependency injection
,scoping
and anevent bus
. CDI beans are the most flexible with respect to injection and scoping. The event bus is very lightweight and very well suited for even the simplest of web applications. In addition to this, CDI also exposes a very advanced feature calledportable extensions
, which is a kind of plug-in mechanism for vendors to provide extra functionality to Java EE that can be made available on all implementations (Glassfish, JBoss AS, Websphere, etc).EJB3 beans were retrofitted from the old legacy EJB2 component model* and were the first beans in Java EE to be managed beans via an annotation. EJB3 beans feature
dependency injection
,declarative transactions
,declarative security
,pooling
,concurrency control
,asynchronous execution
andremoting
.Dependency injection in EJB3 beans is not as flexible as in CDI beans and EJB3 beans have no concept of scoping. However, EJB3 beans are transactional and pooled by default**, two very useable things that CDI has chosen to leave in the domain of EJB3. The other mentioned items are also not available in CDI. EJB3 has no event bus of its own though, but it does have a special type of bean for listening to messages; the message driven bean. This can be used to receive messages from the Java Messaging System or from any other system that has a JCA resource adaptor. Using full blown messaging for simple events is far more heavyweight than the CDI event bus and EJB3 only defines a listener, not a producer API.
JSF Managed Beans have existed in Java EE ever since JSF was included. They too feature
dependency injection
andscoping
. JSF Managed Beans introduced the concept of declarative scoping. Originally the scopes were rather limited and in the same version of Java EE where EJB3 beans could already be declared via annotations, JSF Managed Beans still had to be declared in XML. The current version of JSF Managed Beans are also finally declared via an annotation and the scopes are expanded with a view scope and the ability to create custom scopes. The view scope, which remembers data between requests to the same page is a unique feature of JSF Managed Beans.Apart from the view scope, there is very little still going for JSF Managed Beans in Java EE 6. The missing view scope in CDI there is unfortunate, since otherwise CDI would have been a perfect super set of what JSF Managed Beans offer. Update: In Java EE 7/JSF 2.2 a CDI compatible @ViewScoped has been added, making CDI indeed that perfect super set. Update 2: In JSF2.3 the JSF managed beans have been deprecated in favour of CDI managed beans.
With EJB3 and CDI the situation is not that clear cut. The EJB3 component model and API offers a lot of services that CDI does not offer, so typically EJB3 cannot be replaced by CDI. On the other hand, CDI can be used in combination with EJB3 - e.g. adding scope support to EJBs.
Reza Rahman, expert group member and implementor of a CDI implementation called CanDI, has frequently hinted that the services associated with the EJB3 component model can be retrofitted as a set of CDI annotations. If that were to happen, all managed beans in Java EE could become CDI beans. This does not mean that EJB3 disappears or becomes obsolete, but just that its functionality will be exposed via CDI instead of via EJB's own annotations like @Stateless and @EJB.
Update
David Blevins of TomEE and OpenEJB fame explains the differences and similarities between CDI and EJB very well on his blog: CDI, when to break out the EJBs
*
Although it's just an increment in version number, EJB3 beans were for the most part a completely different kind of bean: a simple pojo that becomes a "managed bean" by applying a simple single annotation, vs the model in EJB2 where a heavyweight and overly verbose XML deployment descriptor was required for each and every bean, in addition to the bean being required to implement various extremely heavyweight and for the most part meaningless component interfaces.
** Stateless session beans are typically pooled, stateful session beans typically not (but they can be). For both types pooling is thus optional and the EJB spec does not mandate it either way.
CDI:它是关于依赖注入的。这意味着您可以在任何地方注入接口实现。这个对象可以是任何东西,它可以与EJB无关。 这里是如何使用 CDI 注入随机生成器的示例。没有任何关于EJB的内容。当您想要注入非 EJB 服务、不同的实现或算法时,您将使用 CDI(因此您根本不需要 EJB)。
EJB:您确实了解,并且可能您对
@EJB
注释感到困惑 - 它允许您将实现注入到您的服务或其他内容中。主要思想是您注入的类应该由 EJB 容器管理。似乎 CDI 确实了解 EJB 是什么,因此在兼容 Java EE 6 的服务器中,您可以在 servlet 中同时编写这两种内容
,
这可能会让您感到困惑,但这可能是 EJB 和 CDI 之间唯一的桥梁。
当我们谈论 CDI 时,您可以将其他对象注入到 CDI 托管类中(它们应该由 CDI 感知框架创建)。
CDI 还提供什么...例如,您使用 Struts 2 作为 MVC 框架(仅示例),即使使用 EJB 3.1,您也受到限制 - 您不能在 Struts 中使用
@EJB
注释动作,它不受容器管理。但是当您添加 Struts2-CDI 插件时,您可以为同一件事编写@Inject
注释(因此不再需要 JNDI 查找)。这样它增强了 EJB 的功能,但是正如我之前提到的,您用 CDI 注入的内容 - 是否与 EJB 相关并不重要,这就是它的功能。附言。更新了示例的链接
CDI: it is about dependency injection. It means that you can inject interface implementation anywhere. This object can be anything, it can be not related to EJB. Here is an example of how to inject random generator using CDI. There is nothing about EJB. You are going to use CDI when you want to inject non-EJB services, different implementations or algorithms (so you don't need EJB there at all).
EJB: you do understand, and probably you are confused by
@EJB
annotation - it allows you to inject implementation into your service or whatever. The main idea is that class, where you inject, should be managed by EJB container.Seems that CDI does understand what EJB is, so in Java EE 6 compliant server, in your servlet you can write both
and
that's what can make you confusing, but that's probably the only thing which is the bridge between EJB and CDI.
When we are talking about CDI, you can inject other objects into CDI managed classes (they just should be created by CDI aware frameworks).
What else CDI offers... For instance, you use Struts 2 as MVC framework (just example), and you are limited here, even using EJB 3.1 - you can't use
@EJB
annotation in Struts action, it is not managed by container. But when you add Struts2-CDI plugin, you can write there@Inject
annotation for the same thing (so no more JNDI lookup needed). This way it enhances EJB power, but as I mentioned before, what you inject with CDI - it does not matter if it is related to EJB or not, and that's its power.PS. updated link to the example
Albert Einstein:
如果你不能简单地解释它,说明你还没有理解它
Ejbs 和 CDI 非常容易理解。
Ejbs:
@Stateless
CarMaker 使用特定的 Ejbs 范围进行注释,因此,它是 Ejb
CDI:
它总是依赖的。让我用例子来解释“依赖”:
类规范{
私有字符串颜色;
私有字符串模型;
//- Getter 和 Setter
}
Specification 类是 CDI,因为它没有用 Ejb 范围进行注释,而且它必须由您的代码而不是 EE 框架初始化。
这里需要注意的一点是,由于我们没有对
Specification
类进行注解,所以它默认是通过@Dependent
注解进行注解的。延伸阅读:
您需要对Ejbs范围注释和CDI范围注释进行更多研究,这将进一步明确概念。Albert Einstein:
If you can't explain it simply, you don't understand it well enough
Ejbs and CDI are pretty simple to understand.
Ejbs:
@Stateless
The CarMaker is Annotated with specific Ejbs scope, therefore, it's Ejb
CDI:
It is always dependent. let me explain "Dependent" with example:
class Specification {
private String color;
private String model;
//- Getter and Setter
}
The
Specification
class is CDI, since it is not annotated with Ejb scopes and also this has to initialized by your code not EE framework.One point to be noted here is that since we didn't Annotated the
Specification
class, it is by default Annotated by@Dependent
annotation.Further reading:
You need to study more between Ejbs scope annotation and CDI scope annotation, that will further clear the conceptl