什么是 EJB,它有什么作用?

Posted

技术标签:

【中文标题】什么是 EJB,它有什么作用?【英文标题】:What is an EJB, and what does it do? 【发布时间】:2012-10-04 01:44:51 【问题描述】:

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

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

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

EJB学习初学者请注意:

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

【问题讨论】:

相关:When is it necessary or convenient to use Spring or EJB3 or all of them together? 【参考方案1】:

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

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

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

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

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

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

    通过注入非常简单的资源/依赖项访问。 容器将查找资源并将资源引用设置为实例字段 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;    
    

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

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

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

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

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

    真正的踢球者:简单。以上都可以用 非常精简的代码 - 要么使用 EJB 的默认设置 在 Java EE 6 中,或添加一些注释。编码 您自己的 POJO 中的企业/工业实力特征将 方式更多,更复杂,更容易出错。一旦您 开始使用 EJB 进行编码,它们很容易开发,并提供一系列“搭便车”的好处。

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

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

当你提到事务时——你指的是持久性? 是的,但不仅如此。 EJB 容器提供分布式 JTA 事务管理器,支持单个事务中的多个资源。例如,您可以在单个事务中更新数据库中的一些数据,并发送一些 JMS 消息。如果有任何失败,一切都会被回滚:数据库更新和发送的消息。 @JBNizet 请原谅我对旧线程发表评论,但不是像 Spring 这样的 EJB 框架提供您提到的这些服务。我不明白区别 基本原理是一样的。 Spring 从 EJB 中获取想法,反之亦然。但是 API、实现、部署方式和一些特性是不同的。 @JB Nizet 在 MVC 模式中,您一般会将 EJB 放在哪里?我会说它们属于模型层,尽管我认识很多人说他们是控制器。如果 EJB 包含业务逻辑(您说它们包含),那么根据定义它们就是模型层。【参考方案3】:

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

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

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

其次,因为 bean 而不是客户端包含 应用程序的业务逻辑,客户端开发人员可以专注于 客户的介绍。客户端开发人员不必编码 实现业务规则或访问数据库的例程。作为一个 结果,客户更瘦了,这是一个特别的好处 对于在小型设备上运行的客户端很重要。

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

何时使用 Enterprise Beans 您应该考虑使用 Enterprise 如果您的应用程序具有以下任何要求,则为 bean:

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

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

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

【讨论】:

【参考方案4】:

我最感兴趣的问题是如何以及在哪里使用它们。要理解这一点,我们首先需要了解存在哪些类型的 EJB。有两大类:

    会话 bean 消息驱动的 bean

让我们考虑会话 Bean。它们分为 3 种:

    有状态的 - 这些组件维护状态并且特定于跨多个请求的客户端。将其视为一个会话。这些可以立即用于购物车或其他类型的会话(登录会话等) 无状态 - 这些是独立的组件,不会在请求之间保留信息,但它们是用户独有的。想到的立即使用 - 服务层中的服务类。想象一下OrderService。这些的另一个重要用途是公开 Web 服务。同样,这在服务层中或完全独立。 单例 - 这些是每个应用程序存在的 bean,创建一次,可以多次重用/访问。立即想到 Configuration 组件 - 您可以在其中存储应用程序级配置并在需要时随时随地访问它们。

现在其他功能或特性可以在任何此类情况下跨层使用:

安全性 - 您可以通过对所调用方法的注释来检查权限。如果您愿意,这可以在服务层以及控制器中发生。 事务管理 - 这是服务层或持久层的明显候选者 依赖注入 - 再次将在任何地方使用

现代的一大用途是所谓的微服务和面向服务的架构。您可以将一些业务逻辑组件打包为 EJB 并在整个组织中分发它们,以供多个客户端使用(这里的客户端是指其他后端应用程序)。

等等。现在最大的缺点是您变得非常依赖 EJB 容器,尽管您可以在 2 个参考实现之间切换,但您将无法切换到更轻量级的东西——例如 Tomcat。但是你为什么要牺牲所有的好处呢?

【讨论】:

【参考方案5】:

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

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

【讨论】:

以上是关于什么是 EJB,它有什么作用?的主要内容,如果未能解决你的问题,请参考以下文章

什么是`S_ISREG()`,它有什么作用?

什么是修饰符?它有什么作用?举例说明

CDATA 到底是啥,它有啥作用?

什么是 SSIS 包,它有什么作用?

QEMU是啥软件?它有啥作用.用来干啥?

什么是OSPF协议?它有什么作用?