Answers:
CDI:关于依赖注入。这意味着您可以在任何地方注入接口实现。该对象可以是任何东西,可以与EJB不相关。这是如何使用CDI注入随机生成器的示例。与EJB无关。当您要注入非EJB服务,不同的实现或算法时,将使用CDI(因此您根本不需要EJB)。
EJB:您确实了解,并且可能对@EJB
注解感到困惑-它允许您将实现注入到您的服务或任何其他内容中。主要思想是,您在其中注入的类应由EJB容器管理。似乎CDI确实了解EJB是什么,因此在Java EE 6兼容服务器中,您可以在servlet中编写两个
@EJB EJBService ejbService;
和
@Inject EJBService ejbService;
那会让您感到困惑,但这可能是EJB和CDI之间的唯一桥梁。
当我们谈论CDI时,您可以将其他对象注入CDI管理的类中(它们仅应由CDI感知框架创建)。
CDI还提供了什么...例如,您将Struts 2用作MVC框架(仅作为示例),即使在使用EJB 3.1的情况下,也受到了限制-您不能@EJB
在Struts操作中使用注释,它不是由容器管理的。但是,当您添加Struts2-CDI插件时,您可以在此处@Inject
为同一内容编写注释(因此,无需进行其他JNDI查找)。这样,它可以增强EJB的功能,但是正如我之前提到的,您要使用CDI注入的内容-它与EJB是否相关都没有关系,这就是它的功能。
PS。更新到示例的链接
当前确实确实有些混乱,因为Java EE中现在有多个组件模型。它们是CDI,EJB3和JSF托管Bean。
CDI是新手。CDI豆功能dependency injection
,scoping
以及event bus
。CDI bean在注入和作用域方面最灵活。事件总线非常轻巧,非常适合于最简单的Web应用程序。除此之外,CDI还公开了一个非常高级的功能,称为portable extensions
,这是一种插件机制,供供应商向Java EE提供可在所有实现(Glassfish,JBoss AS,Websphere等)上使用的额外功能。 。
EJB3 bean是从旧的遗留EJB2组件模型*改造而来的,并且是Java EE中第一个通过注释进行管理的bean。EJB3 Bean有dependency injection
,declarative transactions
, declarative security
,pooling
,concurrency control
,asynchronous execution
和remoting
。
EJB3 bean中的依赖注入不像CDI bean中那样灵活,并且EJB3 bean没有范围界定的概念。但是,EJB3 bean是事务性的,并且默认情况下为**,这是CDI选择留在EJB3域中的两个非常有用的东西。CDI中也没有其他提到的项目。EJB3虽然没有自己的事件总线,但是它确实有一种特殊的Bean来侦听消息。消息驱动的bean。它可用于接收来自Java消息系统或具有JCA资源适配器的任何其他系统的消息。与简单的事件相比,使用完整的消息传递要比CDI事件总线更为繁重,而EJB3仅定义一个侦听器,而不是生产者API。
自从包含JSF以来,Java EE中就已经存在JSF托管Bean。他们也有特色dependency injection
和scoping
。JSF Managed Beans引入了声明性作用域的概念。最初,范围是相当有限的,并且在已经可以通过注释声明EJB3 bean的同一版本的Java EE中,仍然必须以XML声明JSF受管Bean。最后,还将通过注释声明当前版本的JSF托管Bean,并使用视图范围和创建自定义范围的功能来扩展范围。视图范围可以记住对同一页面的请求之间的数据,这是JSF托管Bean的独特功能。
除了视图范围之外,Java EE 6中的JSF托管Bean几乎没有用。不幸的是,缺少CDI的视图范围是不幸的,因为否则CDI将是JSF托管Bean提供的完美的超级集。更新:在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规范没有强制采用任何一种方式。
艾尔伯特爱因斯坦: If you can't explain it simply, you don't understand it well enough
Ejbs和CDI很容易理解。
Ejbs:
@Stateless
public class CarMaker(){
public void createCar(Specification specs){
Car car = new Car(specs);
}
}
CarMaker具有特定的Ejb范围注释,因此,它是Ejb
CDI:
它始终是依赖的。让我用示例解释“从属”:
class Specification {
private String color;
private String model;
//- Getter and Setter
}
该Specification
班是CDI,因为它不使用EJB范围注释,也这已经被你的代码不EE框架进行初始化。这里要注意的一点是,由于我们没有对Specification
类进行注释,因此默认情况下它是通过注释进行@Dependent
注释的。
@Dependent <- By default added
class Specification { ... }
Further reading:
您需要在Ejbs范围注释和CDI范围注释之间进行更多研究,这将进一步澄清概念。