提问人:Raedwald 提问时间:4/7/2011 更新时间:11/5/2013 访问量:16994
EJB 有什么用
What use are EJBs
问:
我目前正在学习Jave-EE,拥有丰富的C++经验,并且已经学习了Java SE。我不明白Enterprise Java Beans的用途;有人可以为我澄清一下吗?我对遗留用途不感兴趣:这是在 EJB-3.1 和 Java-EE 6 的上下文中。
似乎有人用它们来包含业务逻辑,用于实现常规 3 层架构的业务层。这将域逻辑与域对象分离,导致域模型贫血。但这违背了我所有的 OOD 直觉;我同意马丁·福勒(Martin Fowler)的观点,这是一种反模式。我是否应该放松对贫血领域模型的反对意见?还是 EJB 有其他用途?
答:
您已经引用了“实现业务逻辑”用例。
EJB - 在 EJB 3.x 会话 Bean、消息驱动 Bean 和 3.1 中,新的单例 Bean 确实允许您实现业务逻辑。 会话 Bean 通常作为客户端连接到的 Facade 进行服务器。这些客户端可以是 Servlet,通过 HTTP 等方式提供内容,也可以是“胖”客户端,通过其他(更二进制的)协议与 EJB 通信。
消息驱动 Bean 充当异步通信的端点,并且可以调用会话 Bean 上的方法作为示例。
所有 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-stateless-session-beans-和-stateful-session-bean
使用 Java EE 并不意味着领域模型贫乏,就像你可以用 java 编写代码一样,不能很好地利用最佳实践并不意味着它在 java 中是不可能的。我相信 Martin Fowler 的观点是 J2EE(注意使用 J2EE 而不是 Java EE)几乎是强制执行逻辑和数据操作。使用基于 POJO 的实体可以对数据和行为进行适当的建模。EJB 中的“业务逻辑”通常协调业务逻辑的应用程序,但通常不会实际执行它,它通常是一个非常薄的包装器。
因此,EJB 构成了您的服务 API,无论您使用哪个平台/框架,您都需要这个,您需要有一些可以物理调用的东西,它是一个入口点。无论您是使用 spring、Web 服务等实现......你需要一个服务层,没有什么能阻止它在 Java EE 中实现的。一个相当做作的例子
@Stateless
public SomeServiceImpl implements SomeService
someServiceMethod() {
delegate.doSomething();
}
}
public SomeServiceDelegate implements SomeService
someServiceMethod() {
modelObject.doSomething();
}
}
我不想讨论为什么更喜欢 EJB 而不是任何其他技术,只是想指出,使用它们并不意味着你的实现不能使用最佳实践。
评论
只是个人经验的一句话......
我不怀疑 EJB 的好处,但与我合作过后,我认为 EJB 只适合在安全性和交易非常重要的情况下(即:金融应用程序)。对于 90% 的情况,没有 EJB 就没问题了。另一件事......可伸缩性和 EJB 不是好朋友。
评论
正如其他几个答案所表明的那样,EJB 非常适合实现服务层。它们是 Java EE 中一种非常现代、轻量级的 bean。尽管有这个名字,但你不能将它们与 J2EE 中严厉的重量级 EJB2 野兽相提并论。每个人都同意这是一场灾难,但现在不再是 2002 年了。
自 EJB3 (2006) 以来,EJB bean 一直是一项完美的技术。
它们通过提供声明性事务(如果一个事务尚未进行,每个输入方法都会自动启动事务,尽管如果需要可以更改),池化,安全性,锁定,远程处理等等,它们在这里有很大帮助。有关其他详细信息,请参阅以下答案:
这里已经解释了事务,但要补充一点:它不仅仅是高度复杂、高度安全的系统才需要的东西。我甚至会说,即使只处理数据库,这也是一个基本要求。如果我处理一个简单的订单,我希望库存和订单都更新,或者根本不更新。这与在数据库中具有 PK 和 FK 一样基本,以确保完整性。
EJB 使管理事务变得微不足道。如果没有 EJB,就有很多用于启动、提交或回滚 tx 的样板代码。
也不应低估 EJB 提供的池化和存根的好处。这意味着一个 Bean 可以注入很多 EJB,您不必担心每次创建这样的 Bean 时都会实例化它们。否则,当并非所有 EJB 每次都使用时,这将特别麻烦。
然而,由于池化,只注入非常轻量级的存根,这更类似于一种指向实际实例的 URL。这些在内存或 CPU 开销方面几乎没有成本。
EJB 还具有注释,以声明它们是单例,安排它们的锁定行为(写锁/读锁),声明应该在启动时启动一个,允许它们管理所谓的扩展持久性上下文(不限于 TX 的持久性上下文)等。
这些都是你不希望在你的苗条实体中出现的问题。例如,在许多体系结构中,User 对象是一个简单的数据实体,我想跨层发送。我不希望我的 User 实例具有 sendMsg() 方法并将 JMS 资源作为依赖项,以便可以突然从某个客户端发送消息。我真的不确定为什么人们认为这在某种程度上是“自然”和“OOP”。
在现实世界中,每当我想给我的朋友 Joe 发送明信片时,我也不会对他调用 sendMsg 操作。取而代之的是,我写一张卡片,然后把它带到邮局或放在邮筒里。
我也不会在蛋糕上调用 bake() 操作。相反,我把蛋糕放在烤箱里,等等。
评论
有些人在这样的讨论中说,EJB 在此之前在 EJB3 中变得有用,但事实并非如此。 是的,它变得更强大,特别是 JPA,但 EJB1.0 和 EJB2.1 仍然做了很多。 也许他们没有在大型应用程序中使用它,所以他们这么说。
例如,POJO 无法处理事务,因此在 EJB 中,您可以指定特定方法的事务类型,该方法是否需要新事务,或者它不是来自事务。
在我的组织中,我们使用从头开始构建ERP,我们在业务逻辑中使用EJB,这是从2000年开始的,EJB是1.0版。 它不仅将业务层与其他梯也分开,而且还将系统彼此分开, 例如: 财务模块与人力资源模块是分开的。 如果他们想添加一个新模块,他们可以在不重新启动系统的情况下添加它,它将以完美的方式与系统集成。
并在 EJB 中记住这一点: 你在代码中看到的什么都不是,EJB 容器为你做的就是:)的一切。
评论