什么是 EJB,它做什么?

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

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

请只参考更新的信息,即 EJB 3.1。关于 EJB 的过时信息可能会引起误解。

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

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

88342 次浏览

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

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

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

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

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

  2. 可伸缩性和可靠性 如果您应用来自各种调用消息/进程的大量请求 /线程,它们首先分布在池中可用的 EJB 实例之间 这意味着如果每秒传入的请求数是 超出服务器能够处理的范围,我们会优雅地退化——总会有一些 请求被有效地处理,而多余的请求被迫等待 不要到达服务器“熔毁”-其中所有请求经历可怕的响应时间 同时,加上服务器试图访问比硬件和操作系统更多的资源 EJB 可以部署在单独的层上,这些层可以 集群-这通过从一个服务器到另一个服务器的故障转移提供可靠性,另外 硬件可以按比例线性增加

  3. 并发管理。 容器确保 EJB 实例被自动安全地(串行地)访问 容器管理 EJB 池、线程池、 调用队列,并自动执行方法级写锁定(默认)或 读锁定(通过@Lock (READ)) 并发的写-写冲突,并通过防止 读写冲突。
    这主要对@Singleton 会话 bean 有用,其中 bean 正在操作和 在客户端调用方之间共享公共状态 为并发代码执行配置或以编程方式控制高级方案 和数据访问

  4. 自动事务处理。
    什么都不做,所有的 EJB 方法都会运行 如果您使用 JPA 或 JDBC 访问数据库,它将自动 JMS 和 JCA 调用也是如此 @ TransactionAttribute (some TransactionMode)放在方法之前,以指定是否/如何 特定的方法参与 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 来说是完美的 则在新事务中创建新的持久性上下文,所有 检索/写入数据库的实体对象实例只能在 方法调用,并与其他方法隔离 由该方法调用,容器传播并向它们共享相同的 PC,因此相同 实体是自动共享的一致的方式,通过 PC 在同一 交易。
    如果声明了@Statesession bean,则通过以下方法实现与 JPA 的等智能关联 声明 entityManager 为扩展范围之一: @ PersisentContent (unitName = “ AccountsPU,type = EXTENDED) Bean 会话,跨多个 bean 调用和事务,缓存内存中的副本 以前检索/编写的数据库实体,因此不需要重新检索

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

  8. 保安管理。 以角色为基础的存取控制可以通过简单的注释或 XML 进行配置 服务器将自动传递经过身份验证的用户详细信息 调用作为安全上下文(调用主体和角色) 规则将自动强制执行,以便方法不会被 它允许 EJB 轻松地访问用户/角色细节以获得额外的编程 它允许插入额外的安全处理(甚至 IAM 工具)到 以标准的方式

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

  10. 真正的挑战: 简单。以上所有都可以做到 非常简化的代码-或者使用 EJB 的默认设置 或者添加一些注释 你自己的 POJO 中的企业/行业强度特性 使 方式更加庞大、复杂和容易出错 开始使用 EJB 编写代码,它们非常容易开发,并且提供了一系列“免费”的好处

在10年前的最初 EJB 规范中,EJB 是一个主要的生产力问题。它们非常臃肿,需要大量的代码和配置工件,并且提供了上述好处的2/3。大多数网络项目实际上并没有使用它们。但是,经过10年的调整、全面检修、功能增强和开发流程管理,这种情况已经发生了显著变化。在 JavaEE6中,它们提供了最大级别的工业强度和简单的使用。

有什么不喜欢的

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

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

企业豆的好处出于几个原因,企业豆 简化大型分布式应用程序的开发, 因为 EJB 容器为企业提供系统级服务 Bean,bean 开发人员可以集中精力解决业务 EJB 容器,而不是 bean 开发人员,是 负责系统级服务,如事务管理 和安全授权。

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

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

何时使用企业 bean 您应该考虑使用企业 bean 如果您的应用程序具有下列任何一项要求:

应用程序必须是可伸缩的 用户,您可能需要将应用程序的组件分布到 多台机器。不仅可以企业的应用程序的 bean 运行在不同的机器上,但它们的位置也将保持不变 对客户透明。

事务必须确保数据完整性 事务的并发访问管理机制 共享的东西。

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

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

  1. 会话豆
  2. 消息驱动的豆子

让我们考虑一下会话豆,它们有三种:

  1. 有状态的 -这些组件维护状态,并且特定于跨多个请求的客户端。把它当成一次治疗。这些会话可以立即用于 手推车或其他类型的会话(登录会话等)
  2. 无状态 -这些是自包含的组件,它们不会在请求之间持久化信息,但是对于用户来说是独一无二的。立即使用的想法-服务层中的服务类。想象一下 OrderService。它们的另一个重要用途是公开 Web 服务。同样,这是在服务层或完全独立。
  3. Singleton -这些是每个应用程序存在的 bean,只创建一次,可以重用/访问多次。随即想到的是 Configuration组件——您可以在其中存储应用程序级别的配置,并在需要时从任何地方访问它们。

现在,其余的功能或特性可以在任何这样的情况下跨层使用:

  • Security -可以使用调用的方法上的注释检查权限。如果您愿意,这可以在服务层和控制器中发生。
  • 事务管理 ——这是服务层或持久层中显而易见的候选者
  • 依赖注入 -同样会在任何地方使用

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

诸如此类。现在最大的缺点是您变得非常依赖于 EJB 容器,尽管您可以在两个引用实现之间切换,但是您不能切换到更轻量级的东西——例如 Tomcat。但你为什么要牺牲所有的利益呢?

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

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