161

一直在尝试了解EJBbean 是什么,它们的实例在池中管理是什么意思,等等。实在抓不住他们。

你能解释一下它们的真正含义吗(实际上对于 Java 程序员来说)?他们在做什么?他们的目的是什么?为什么要真正使用它们?(为什么不坚持POJO?)也许是一个示例应用程序?

请仅参考更新信息,即EJB 3.1. 有关 EJB 的过时信息可能会产生误导。

对于 EJB 学习初学者请注意:

EJB 基于分布式对象,这是指运行在通过网络链接的多台机器(虚拟机或物理机)上的软件片段。

4

5 回答 5

168

为什么要真正使用它们?(为什么不只坚持 POJO?)

如果您需要一个组件来访问数据库,或访问其他连接/目录资源,或从多个客户端访问,或打算用作 SOA 服务,那么今天的 EJB 通常“更大、更强、更快(或至少更具可扩展性)并且比 POJO 更简单”。它们对于通过 Web 或公司网络为大量用户提供服务最有价值,而对于部门内的小型应用程序则价值较低。

  1. 通过松散耦合在多个应用程序/客户端之间重用/共享逻辑。
    EJB 可以打包在自己的 jar 中、部署并从很多地方调用。它们是通用组件。诚然,POJO 可以(小心!)设计为库并打包为 jar。但是 EJB 支持本地和远程网络访问 - 包括通过本地 java 接口、透明 RMI、JMS 异步消息和 SOAP/REST Web 服务,从具有多个(不一致?)部署的剪切和粘贴 jar 依赖项中保存。
    它们对于创建 SOA 服务非常有用。当用于本地访问时,它们是 POJO(添加了免费容器服务)。设计一个单独的 EJB 层的行为促进了对最大化封装、松散耦合和内聚的额外关注,并促进了一个干净的接口(外观),使调用者免受复杂的处理和数据模型的影响。

  2. 可扩展性和可靠性 如果您应用来自各种调用消息/进程/线程的大量请求,它们首先分布在池中的可用 EJB 实例中,然后排队。这意味着如果每秒传入请求的数量大于服务器可以处理的数量,我们会优雅地降级 - 总是有一些请求被有效处理,多余的请求被等待。我们没有到达服务器“崩溃”——所有请求同时经历可怕的响应时间,而且服务器试图访问比硬件和操作系统可以处理的更多的资源,因此崩溃。EJB 可以部署在可以集群的单独层上——这通过从一台服务器到另一台服务器的故障转移提供了可靠性,此外还可以添加硬件以实现线性扩展。

  3. 并发管理。容器确保 EJB 实例被多个客户端安全(串行)自动访问。容器管理EJB池、线程池、调用队列,并自动进行方法级别的写锁定(默认)或读锁定(通过@Lock(READ))。这可以防止数据因并发写入-写入冲突而损坏,并通过防止读写冲突来帮助一致地读取数据。
    这主要对@Singleton 会话 bean 有用,其中 bean 在客户端调用者之间操作和共享公共状态。这可以很容易地被覆盖以手动配置或以编程方式控制并发代码执行和数据访问的高级场景。

  4. 自动交易处理。
    什么都不做,所有的 EJB 方法都在 JTA 事务中运行。如果您使用 JPA 或 JDBC 访问数据库,它会自动加入事务。JMS 和 JCA 调用也是如此。在方法之前指定 @TransactionAttribute(someTransactionMode) 以指定该特定方法是否/如何参与 JTA 事务,覆盖默认模式:“必需”。

  5. 通过注入非常简单的资源/依赖项访问。
    容器将在 EJB 中查找资源并将资源引用设置为实例字段:例如 JNDI 存储的 JDBC 连接、JMS 连接/主题/队列、其他 EJB、JTA 事务、JPA 实体管理器持久化上下文、JPA 实体管理器工厂持久化单元和JCA 适配器资源。例如设置对另一个 EJB & 一个 JTA 事务 & 一个 JPA 实体管理器 & 一个 JMS 连接工厂和队列的引用:

    @Stateless
    public class MyAccountsBean {
    
        @EJB SomeOtherBeanClass someOtherBean;
        @Resource UserTransaction jtaTx;
        @PersistenceContext(unitName="AccountsPU") EntityManager em;
        @Resource QueueConnectionFactory accountsJMSfactory;
        @Resource Queue accountPaymentDestinationQueue;
    
        public List<Account> processAccounts(DepartmentId id) {
            // Use all of above instance variables with no additional setup.
            // They automatically partake in a (server coordinated) JTA transaction
        }
    }
    

    一个 Servlet 可以在本地调用这个 bean,只需声明一个实例变量:

    @EJB MyAccountsBean accountsBean;    
    

    然后根据需要调用它的方法。

  6. 与 JPA 的智能交互。默认情况下,如上注入的 EntityManager 使用事务范围的持久性上下文。这对于无状态会话 bean 来说是完美的。当调用(无状态)EJB 方法时,会在新事务中创建新的持久性上下文,检索/写入数据库的所有实体对象实例仅在该方法调用中可见,并且与其他方法隔离。但是,如果该方法调用了其他无状态 EJB,则容器会向它们传播并共享同一台 PC,因此相同的实体在同一事务中通过 PC 以一致的方式自动共享。
    如果声明了 @Stateful 会话 bean,则通过将 entityManager 声明为扩展范围之一来实现与 JPA 的同等智能关联:@PersistentContent(unitName="AccountsPU, type=EXTENDED)。这在 bean 会话的生命周期中存在,跨多个 bean 调用和事务,缓存以前检索/写入的 DB 实体的内存副本,因此不需要重新检索它们。

  7. 生命周期管理。EJB 的生命周期由容器管理。根据需要,它创建 EJB 实例,清除和初始化有状态会话 bean 状态,钝化和激活,并调用生命周期回调方法,因此 EJB 代码可以参与生命周期操作以获取和释放资源,或执行其他初始化和关闭行为。它还捕获所有异常,记录它们,根据需要回滚事务,并根据需要抛出新的 EJB 异常或 @ApplicationExceptions。

  8. 安全管理。可以通过简单的注释或 XML 设置来配置对 EJB 的基于角色的访问控制。服务器自动将经过身份验证的用户详细信息与每个调用一起作为安全上下文(调用主体和角色)传递。它确保自动强制执行所有 RBAC 规则,以便方法不会被错误的角色非法调用。它允许 EJB 轻松访问用户/角色详细信息以进行额外的编程检查。它允许以标准方式将额外的安全处理(甚至 IAM 工具)插入容器。

  9. 标准化和可移植性。EJB 实现符合 Java EE 标准和编码约定,提高了质量以及易于理解和维护。它还通过确保它们都支持相同的标准功能和行为,并通过阻止开发人员意外采用专有
    的非可移植供应商功能来促进代码对新供应商应用程序服务器的可移植性。

  10. 真正的踢球者:简单。上述所有操作都可以通过非常精简的代码来完成——或者使用 Java EE 6 中 EJB 的默认设置,或者添加一些注释。在您自己的 POJO中编码企业/工业实力功能将更加庞大、复杂且容易出错。一旦您开始使用 EJB 进行编码,它们就很容易开发并提供一系列“搭便车”的好处。

在 10 年前的原始 EJB 规范中,EJB 是一个主要的生产力问题。它们很臃肿,需要大量代码和配置工件,并提供了上述大约 2/3 的好处。大多数 Web 项目实际上并没有使用它们。但随着 10 年的调整、大修、功能增强和开发流线化,这种情况发生了显着变化。在 Java EE 6 中,它们提供了最高级别的工业强度和易用性。

有什么不喜欢的??:-) :-)

于 2012-10-14T05:16:41.850 回答
68

EJB 是一个 Java 组件,包含业务逻辑,部署在容器中,并受益于容器提供的技术服务,通常以声明方式,这要归功于注解:

  • 事务管理:事务可以在调用 EJB 的方法之前自动启动,并在该方法返回时提交或回滚。此事务上下文被传播到对其他 EJB 的调用。
  • 安全管理:可以检查调用者是否具有执行方法所需的角色。
  • 依赖注入:可以将其他 EJB 或 JPA 实体管理器、JDBC 数据源等资源注入 EJB。
  • 并发性:容器确保一次只有一个线程调用 EJB 实例的方法。
  • 分发:可以从另一个 JVM 远程调用一些 EJB。
  • 故障转移和负载平衡:如果需要,EJB 的远程客户端可以自动将其调用重定向到另一台服务器。
  • 资源管理:有状态 bean 可以自动钝化到磁盘,以限制服务器的内存消耗。
  • ...我可能忘记了一些观点。
于 2012-10-13T11:44:03.230 回答
22

希望 Oracle 文档中的这篇文章能帮助像我这样的人以简单的方式理解 EJB 的主题。

什么是企业 Bean?用 Java 编程语言编写的企业 bean 是一个服务器端组件,它封装了应用程序的业务逻辑。业务逻辑是实现应用程序目的的代码。例如,在库存控制应用程序中,企业 bean 可能在称为 checkInventoryLevel 和 orderProduct 的方法中实现业务逻辑。通过调用这些方法,客户端可以访问应用程序提供的库存服务。

Enterprise Beans 的好处 出于几个原因,Enterprise Beans 简化了大型分布式应用程序的开发。首先,因为 EJB 容器为企业 bean 提供系统级服务,所以 bean 开发人员可以专注于解决业务问题。EJB 容器,而不是 bean 开发者,负责系统级服务,例如事务管理和安全授权。

其次,因为 bean 而不是客户端包含应用程序的业务逻辑,所以客户端开发人员可以专注于客户端的呈现。客户端开发人员不必编写实现业务规则或访问数据库的例程。结果,客户端变得更瘦了,这对于在小型设备上运行的客户端来说尤其重要。

第三,因为企业 bean 是可移植的组件,应用程序组装器可以从现有的 bean 构建新的应用程序。这些应用程序可以在任何兼容的 Java EE 服务器上运行,只要它们使用标准 API。

何时使用企业 Bean 如果您的应用程序具有以下任何要求,则应考虑使用企业 Bean:

应用程序必须是可扩展的。为了适应越来越多的用户,您可能需要将应用程序的组件分布在多台机器上。应用程序的企业 bean 不仅可以在不同的机器上运行,而且它们的位置对客户端也将保持透明。

事务必须确保数据完整性。企业 bean 支持事务,即管理共享对象的并发访问的机制。

该应用程序将有各种客户端。只需几行代码,远程客户端就可以轻松找到企业 bean。这些客户端可以是瘦的、多样的和众多的。

于 2015-11-06T10:10:27.720 回答
4

The question that interests me most is how and where can I use them. To understand this, we need first to see what types of EJBs exist. There are 2 big categories:

  1. Session beans
  2. Message driven beans

Let's consider Session Beans. They are of 3 kinds:

  1. Stateful - these components maintain state and are specific for a client across multiple requests. See it as a session. The immediate use these could be put to is shop carts or other type of sessions (login session and so on)
  2. Stateless - these are self contained components that don't persist information between requests, but they are unique to the user. Immediate use that comes to mind - Service classes in the service layer. Imagine OrderService. Another big use for these is to expose web services. Again, this be in the Service layer or totally separate.
  3. Singleton - these are the beans that exist per application and are created once and can be reused / accessed multiple times. Immediately the Configuration component comes to mind - where you can store application level configs and access them when you need them from anywhere.

Now the rest of the capabilities or features can be used across layers in any such situations:

  • Security - you can check for permissions with an annotation on the method that is called. This can happen in the Service layer as well as in Controller if you wish so.
  • Transaction management - this is the obvious candidate in the Service layer or Persistence layer
  • Dependency Injection - again will be used everywhere

One big use in modern times are the so called Microservices and Service Oriented Architectures. You can package some business logic components as EJBs and distribute them across the organization, to be used by multiple clients (by client here I mean other back-end applications).

And so on. Now the big drawback is that you become very dependent on the EJB container and although you could switch between 2 reference implementations, you will not be able to switch to something lighter - Tomcat for example. But why would you want to sacrifice all the benefits?

于 2017-09-22T23:26:26.563 回答
0

EJB 是分层应用程序中业务逻辑所在的位置。遵循该模型,层(不同于层)可以从用户和其他接口独立访问,因此它们可以被具有多种协议的多个组件部署和访问。

在规范化系统模型中,EJB 是“动作”和“工作流”,而 Servlet 是“接口”,JCA 是“连接器”,定时器和 JMS 是“事件”。

于 2021-09-23T17:59:18.033 回答