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

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

你能解释一下他们究竟是什么(实际上是一个Java程序员)? 他们在做什么? 他们的目的是什么? 为什么真的使用它们? (为什么不坚持POJO ?)也许是一个示例应用程序?

请仅参考更新的信息,即EJB 3.1 。 有关EJB的date信息可能会引起误解。

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

EJB是基于分布式对象的 ,这是指在networking上连接的多个虚拟或物理机器上运行的软件。

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

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

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

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

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

  4. 自动事务处理。
    什么也不做,所有的EJB方法都在JTA事务中运行。 如果使用JPA或JDBC访问数据库,则会自动登记到事务中。 JMS和JCA调用也一样。 在方法之前指定@TransactionAttribute(someTransactionMode)来指定该特定方法是否参与JTA事务,并覆盖默认模式:“必需”。

  5. 通过注入非常简单的资源/依赖访问。
    容器将查找资源并将资源引用设置为EJB中的实例字段:例如JNDI存储的JDBC连接,JMS连接/主题/队列,其他EJB,JTA事务,JPA实体pipe理器持久性上下文,JPA实体pipe理器工厂持久性单元以及JCA适配器资源。 例如设置对另一个EJB&JTA事务&JPA实体pipe理器&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,只需要声明一个实例variables:

     @EJB MyAccountsBean accountsBean; 

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

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

  7. 生命周期pipe理。 EJB的生命周期是容器pipe理的。 根据需要,它创buildEJB实例,清除和初始化有状态会话bean状态,钝化和激活以及调用生命周期callback方法,以便EJB代码可以参与生命周期操作以获取和释放资源,或执行其他初始化和closures行为。 它还捕获所有exception,logging它们,根据需要回退事务,并根据需要抛出新的EJBexception或@ApplicationExceptions。

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

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

  10. 真正的踢球者:简单。 以上所有内容都可以通过非常简化的代码来完成 – 可以使用Java EE 6中EJB的默认设置,也可以添加一些注释。 在你自己的POJO中编码企业/工业强度特征将会更加庞大,复杂和容易出错。 一旦你开始使用EJB进行编码,它们就相当容易开发,并提供了一个很好的“搭便车”的好处。

在十年前的原始EJB规范中,EJB是一个主要的生产力问题。 他们臃肿,需要大量的代码和configuration文件,并提供了2/3以上的好处。 大多数Web项目并没有真正使用它们。 但是经过10年的调整,检修,function提升和发展stream水线,这个变化已经显着。 在Java EE 6中,它们提供最大程度的工业实力和简单的使用。

什么是不喜欢? 🙂 🙂

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

  • 事务pipe理:事务可以在调用EJB的方法之前自动启动,并且一旦这个方法返回就提交或者回滚。 这个事务上下文被传播到其他EJB的调用。
  • 安全pipe理:可以检查调用者具有执行该方法的必要angular色。
  • dependency injection:可以将其他EJB或JPA实体pipe理器,JDBC数据源等资源注入到EJB中。
  • 并发性:容器确保一次只有一个线程调用EJB实例的一个方法。
  • 发行版:一些EJB可以从另一个JVM远程调用。
  • 故障转移和负载平衡:如果需要,EJB的远程客户端可以自动将其调用redirect到另一台服务器。
  • 资源pipe理:有状态的bean可以自动被钝化到磁盘,以限制服务器的内存消耗。
  • 我可能已经忘记了一些观点

希望这个来自Oracle的文档能够帮助像我这样的人以简单的方式了解EJB的主题。

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

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

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

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

何时使用企业Bean如果您的应用程序有以下任何需求,您应该考虑使用企业bean:

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

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

应用程序将有多种客户端。 只需几行代码,远程客户端就可以轻松定位企业bean。 这些客户可以很薄,种类繁多。

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

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

我们来考虑Session Bean。 他们有三种:

  1. 有状态的 – 这些组件维护状态,并且跨多个请求特定于客户端。 看到它作为一个会议。 这些可以直接使用的是购物车或其他types的会话(login会话等)
  2. 无状态 – 这些是独立的组件,不会在请求之间持续信息,但是它们是用户唯一的。 立即使用,想到服务层的服务类 。 想象一下OrderService 。 另一个重要的用途就是公开Web服务。 再次,这是在服务层或完全分开。
  3. 单例 – 这些是每个应用程序存在的bean,只创build一次,可以重复使用/访问多次。 立即想到Configuration组件,在那里你可以存储应用程序级别的configuration,并在任何地方需要它们时访问它们。

现在,在任何这样的情况下,其余的function或function都可以在层间使用:

  • 安全性 – 您可以使用调用方法的注释来检查权限。 如果你愿意的话,这可以发生在服务层和Controller中。
  • 事务pipe理 – 这是服务层或持久层中的明显候选者
  • dependency injection – 将再次被使用

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

等等。 现在最大的缺点是你变得非常依赖于EJB容器,虽然你可以在2个参考实现之间切换,但是你不能切换到更轻的东西 – 例如Tomcat。 但是,为什么要牺牲所有的好处呢?