EJB的用途是什么

我目前正在学习Jave-EE,拥有丰富的C ++经验并且学过Java SE。 我不明白Enterprise Java Beans的目的; 谁能为我澄清这一点。 我对遗留用途不感兴趣:这是在EJB-3.1和Java-EE 6的上下文中。

似乎有些人使用它们来包含业务逻辑,用于实现传统3层架构的业务层。 这将域逻辑与域对象分开,导致贫血域模型 。 但这违背了我所有的OOD本能; 我同意Martin Fowler认为这是一种反模式 。 我是否应该放松对贫血领域模型的反对意见? 或者EJB有其他用途吗?

使用Java EE并不会自动暗示一个贫血的域模型,就像你可以用java编写代码那样没有充分利用最佳实践并不意味着它在java中是不可能的。 我相信Martin Fowler的观点是J2EE(注意使用J2EE而不是Java EE)几乎强制执行逻辑和数据操作。 使用基于POJO的实体允许适当地建模数据和行为。 EJB中的“业务逻辑”通常编排业务逻辑的应用程序,但通常不会实际执行它,它通常是一个非常薄的包装器。

因此,EJB构成了您的Service API,您需要使用您正在使用的任何平台/框架,您需要拥有可以物理调用的东西,这是一个切入点。 无论您是使用spring,Web服务等实现……您需要一个服务层,没有什么可以阻止它在Java EE中实现。 一个颇为人为的例子

@Stateless public SomeServiceImpl implements SomeService someServiceMethod() { delegate.doSomething(); } } public SomeServiceDelegate implements SomeService someServiceMethod() { modelObject.doSomething(); } } 

我没有考虑更喜欢EJB而不是任何其他技术的原因,只是想指出使用它们并不意味着你的实现不能使用最佳实践。

正如其他几个答案所示,EJB非常适合实现服务层。 它们是Java EE中非常现代,轻量级的bean。 尽管有这个名字,你无法将它们与J2EE中严苛的重型EJB2野兽进行比较。 每个人都认为是一场灾难,但不再是2002年了。

从EJB3(2006)开始,EJB bean就是一种非常精细的技术。

通过提供声明性事务,它们在这里提供了很多帮助(如果一个事务尚未进行,每个入口方法都会自动启动事务,尽管如果需要可以更改它),池化,安全性,锁定,远程处理等等。 有关其他详细信息,请参阅以下答案:

  • 用于分层可重用架构的框架
  • 在什么情况下使用EJB? 它们是否需要在网站/网络应用程序开发中?
  • EJB 3或Hibernate 3
  • @EJB注入与查找 – 性能问题

这里已经解释了交易,但是要补充一点:它不是高度复杂,高度安全的系统所需要的。 即使只处理数据库,我也会说它是一个基本要求。 如果我处理一个简单的订单,我希望库存和订单都更新或两者都没有。 这与在数据库中使用PK和FK以确保完整性一样基本。

EJB使管理事务变得微不足道。 没有EJB,有很多用于启动,提交或回滚tx的样板代码。

人们也不应低估EJB提供的池和存根的好处。 这意味着bean可以注入大量的EJB,并且每次创建这样的bean时都不必担心它们会被实例化。 如果不是每次都使用所有EJB,那么这将特别麻烦。

但是,由于池化,只注入非常轻量级的存根,这更类似于一种指向实际实例的URL。 这些在注入的内存或CPU开销方面几乎没有任何成本。

EJB还具有注释来声明它们是单例,安排它们的锁定行为(写锁定/读锁定),声明应该在启动时启动,允许它们管理所谓的扩展持久化上下文(不限于TX的持久化上下文) )等

这些都是您在苗条实体中不想要的问题。 在许多体系结构中,例如,User对象是我想要跨层发送的简单数据实体。 我不希望我的User实例具有sendMsg()方法并且具有JMS资源作为依赖项,因此可以从某个客户端突然发送消息。 我不确定为什么人们会认为这在某种程度上是“自然的”和“OOP”。

在现实世界中,每当我想给他发明信片时,我也不会对我的朋友Joe调用sendMsg操作。 相反,我发一张卡片并将其带到邮局或放在邮箱中。

我也没有在蛋糕上调用bake()操作。 相反,我把蛋糕放在烤箱等等。

您已经引用了“实现业务逻辑”用例。

EJB – 在EJB 3.x会话Bean,消息驱动Bean和3.1中,新的Singleton Beans确实允许您实现biz逻辑。 会话Bean通常作为客户端连接的Facade服务器。 这些客户端可以是Servlet,通过例如HTTP或“胖”客户端来提供内容,这些客户端通过其他(更多二进制)协议与EJB进行通信。

Message Driven Beans作为异步通信的端点,可以自己调用Session Beans上的方法作为示例。

所有EJB都有一个共同点,这使它们非常有吸引力:它们由容器管理。 因此容器负责实例化,池化,事务,安全性等。

如果你在EJB中写

 @Resource DataSource x; 

容器确保当bean准备好接收方法调用时,变量“x”包含合适的数据源。

Bean的池化允许您有更多的客户端连接到站点而不是没有,因为实例是共享的(无状态SB),或者如果内存紧张则可以通过容器将实例交换到第二存储 – 稍后激活它们。

在EJB 3中,EJB 1.x和2.x中的旧EntityBeans消失了,取而代之的是JPA,它构建了POJO的域数据模型,可以注释为提供关系语义,也可以由外部提供语义。 XML文件。

使用JPA(根本不需要EJB),EJB通常用于实现对这些实体的处理:

 @Stateless public class MyBean { @PersistenceContext EntityManager em; public Foo getFoo(String name) { Query q = em.createQuery("SELECT f FROM Foo f WHERE f.name = :name"); q.setParameter("name",name); return q.getSingleValue(); } } 

几点:

  • EJB本身并不存在; 它们位于EJB容器中,通过它们为您提供一些非常有用的服务,例如声明性安全性,声明性事务和相对容易的集群。
  • 虽然贫血领域模型确实是反模式:一旦您的业务逻辑变得更加复杂,例如当多个应用程序在同一模型上运行时,将大多数逻辑与模型分离就成为关注点分离的问题。

只是个人经历的评论……

我不怀疑EJB的好处,但是曾经使用它们,我认为EJB只适用于安全和事务非常重要的情况(即:财务应用程序)。 对于90%的情况,没有EJB就可以了。 另一件事……可伸缩性和EJB不是好朋友。

有些人在讨论中告诉我这样的EJB在EJB3中变得有用,而不是在那之前,这是不可能的。 它特别适用于JPA变得更强大,但EJB1.0和EJB2.1仍然做了很多。 也许他们没有在大型应用程序中使用它,所以他们这么说。

例如,POJO无法处理Transaction,因此在EJB中您可以为特定方法指定事务类型,因为它需要新事务或者它不是来自事务。

在我的组织中,我们从头开始使用ERP构建,我们在业务逻辑中使用EJB,它来自2000,EJB是版本1.0。 并且它不仅将业务层与其他层分开,而且还将系统彼此分开,例如:财务模块与HR模块分开。 如果他们想要添加一个新模块,他们可以添加它而无需重新启动系统,它将以完美的方式与系统集成。

并在EJB中记住这一点:你在代码中看到的是什么,EJB容器为你做的是每件事:)。

无状态和有状态,企业Java的豆

EJB无状态会话豆和有状态会话bean的