一直在尝试学习什么是 EJB
Bean,以及他们的实例为什么要被池化管理等问题,但无法真正掌握。
你能否解释一下他们到底是什么(对于Java程序员来说有什么实际意义)?他们都做些什么?它们的目的是什么?为什么真的要使用它们?(为什么不坚持使用POJO?)也许可以给出一个示例应用?
请只参考最新信息,即EJB 3.1
。关于EJB的过时信息可能会误导。
对于EJB学习初学者请注意:
EJB基于分布式对象,这指的是在由网络连接的多个计算机(虚拟或物理)上运行的软件部件。
一直在尝试学习什么是 EJB
Bean,以及他们的实例为什么要被池化管理等问题,但无法真正掌握。
你能否解释一下他们到底是什么(对于Java程序员来说有什么实际意义)?他们都做些什么?它们的目的是什么?为什么真的要使用它们?(为什么不坚持使用POJO?)也许可以给出一个示例应用?
请只参考最新信息,即EJB 3.1
。关于EJB的过时信息可能会误导。
对于EJB学习初学者请注意:
EJB基于分布式对象,这指的是在由网络连接的多个计算机(虚拟或物理)上运行的软件部件。
为什么要使用它们?(为什么不只使用POJO?)
如果您需要一个访问数据库、访问其他连接性/目录资源、被多个客户端访问的组件,或者是用作SOA服务的组件,那么现在的EJB通常比POJO更“强大、快速(或至少更可扩展)和简单”。它们最有价值的是为网络或公司网络上的大量用户提供服务,对于部门内的小型应用程序来说,它们略显不足。
通过松耦合实现在多个应用程序/客户端之间共享逻辑。
EJB可以封装为独立的JAR包,部署并从多个位置调用。它们是常见的组件。当然,POJO也可以(小心!)设计为库,并封装为JAR包。但是EJB支持本地和远程网络访问,包括通过本地Java接口、透明RMI、JMS异步消息和SOAP/REST Web服务,避免了使用多个(不一致的?)部署的复制粘贴JAR依赖关系。
它们非常有用于创建SOA服务。当用于本地访问时,它们就是POJO(加上免费容器服务)。设计单独的EJB层促进了更大的关注最大化封装、松耦合和内聚,并促进了一个清晰的接口(Facade),遮蔽调用者复杂的处理和数据模型。
可扩展性和可靠性 如果应用程序从各种呼叫消息/进程/线程中发出大量请求,则它们首先分布在池中的可用EJB实例中,然后排队等待。这意味着,如果每秒传入的请求数量大于服务器可以处理的数量,我们可以优雅地降级——总是有一些请求被高效处理,而多余的请求则等待。我们不会出现服务器“崩溃”——所有请求都同时经历可怕的响应时间,并且服务器试图访问超过硬件和操作系统可以处理的更多资源,从而导致崩溃。EJB可以部署在单独的层上,可以进行集群化——这通过从一个服务器故障转移到另一个服务器来提供可靠性,而且可以添加硬件以实现线性扩展。
并发管理。
容器确保EJB实例由多个客户端安全(串行)访问。容器管理EJB池、线程池、调用队列,并自动执行方法级别的写锁定(默认)或读锁定(通过@Lock(READ))。这样可以防止数据在并发写-写冲突中损坏,并帮助数据通过防止读-写冲突而被一致地读取。
这对于Singleton会话Bean特别有用,因为该Bean正在操作并共享跨客户端调用者的公共状态。这可以轻松地覆盖以手动配置或以编程方式控制并发代码执行和数据访问的高级场景。
自动化事务处理。
什么也不用做,所有EJB方法都在JTA事务中运行。如果使用JPA或JDBC访问数据库,则会自动将其注册到事务中。对于JMS和JCA调用也是如此。在方法之前指定@TransactionAttribute(someTransactionMode)以指定该特定方法如何参与JTA事务,覆盖默认模式:“Required”。
通过注入非常简单地访问资源/依赖项。
容器将查找资源并将资源引用设置为EJB实例字段:例如存储在JNDI中的JDBC连接、JMS连接/主题/队列、其他EJB、JTA事务、JPA实体管理器持久性上下文、JPA实体管理器工厂持久性单元和JCA适配器资源。
例如,设置对另一个EJB、JTA事务、JPA实体管理
@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方法时,在新事务中创建一个新的持久化上下文,所有从DB检索/写入的实体对象实例仅在该方法调用内可见,并与其他方法隔离。 但是,如果方法通过调用其他无状态EJB,则容器会将同一PC传播并共享给它们,因此相同的实体会通过同一事务中的PC以一致的方式自动共享。 如果声明了@Stateful会话bean,则可以通过声明entityManager为扩展范围来实现与JPA的智能关联: @PersistentContent(unitName="AccountsPU, type=EXTENDED)。它存在于bean会话的整个生命周期中,跨多个bean调用和事务,在内存中缓存先前检索/编写的DB实体副本,因此不需要重新检索。
生命周期管理。EJB的生命周期由容器管理。根据需要,它创建EJB实例,清除和初始化有状态会话bean状态,使其处于被动和激活状态,并调用生命周期回调方法,因此EJB代码可以参与生命周期操作以获取和释放资源, 或执行其他初始化和关闭行为。它还捕获所有异常,记录它们,根据需要回滚事务,并抛出新的EJB异常或@ApplicationExceptions。
安全管理。可以通过简单的注释或XML设置配置对EJB的基于角色的访问控制。服务器自动将经过身份验证的用户详细信息与每个调用一起传递作为安全上下文(调用主体和角色)。 它确保自动执行所有RBAC规则,以便方法不能被错误的角色非法调用。它允许EJB轻松访问用户/角色详细信息以进行额外的编程检查。它允许以标准方式向容器插入额外的安全处理(甚至是IAM工具)。
标准化和可移植性。EJB实现符合Java EE标准和编码约定,促进质量和易于理解和维护。它还通过确保它们所有支持相同的标准特性和行为并防止开发人员意外采用专有的非可移植商家特性,从而促进代码到新供应商应用程序服务器的可移植性。
真正的关键点:简单性。所有这些都可以使用非常简化的代码完成-要么使用Java EE 6中的EJB默认设置,要么添加一些注释。在自己的POJO中编写企业/工业强度特性会更加冗长、复杂和容易出错。一旦开始使用EJB进行编码,它们就相当容易开发并提供了一系列“免费乘车”的好处。
在10年前的原始EJB规范中,EJB是一项生产力障碍。它们臃肿、需要大量的代码和配置文件,并且提供的好处只有三分之二左右。大多数 Web 项目实际上并没有使用它们。但是经过10年的调整、彻底改进、功能增强和开发流程优化,这已经发生了显着变化。在Java EE 6中,它们提供了最高级别的工业强度和易用性。
有什么不喜欢的呢??:-) :-)
EJB是一个Java组件,包含业务逻辑,您可以在容器中部署它,并从容器提供的技术服务中受益,通常以声明方式进行注释:
OrderService
。这些的另一个重要用途是公开Web服务。同样,这可以在服务层中或完全分开。Configuration
组件-您可以在其中存储应用程序级别的配置,并在需要时从任何位置访问它们。EJB 是分层应用程序中业务逻辑所在的地方。按照这个模型,一个层(不同于一个层)可以独立地从用户和其他接口访问,因此它们可以通过多个协议部署和访问多个组件。
在规范化系统模型中,EJB 是“操作”和“工作流程”,而 Servlet 将是“接口”,JCA 是“连接器”,计时器和 JMS 是“事件”。