我的应用程序拥有session beans,调度程序并使用Web服务。我最近了解到Apache TomEE,它支持Contexts and Dependency Injection (CDI)。 GlassFish容器也支持CDI。
如果我不需要CDI没有提供的任何功能,我可以替换会话bean吗?那么我可以得到哪些好处?
目前来说,容器所提供的代理服务并不完全相同,但是我们正在Java EE规范层面上进行改进。
请忽略任何你可能会拥有的“轻量级”或“重量级”的印象。那都是市场宣传。就大部分而言,它们具有相同的内部设计。CDI实例解析可能更加复杂,因为它稍微更加动态和上下文相关。相比之下,EJB实例解析则相当静态、简单和愚笨。
从TomEE的实现角度来看,调用EJB与调用CDI bean几乎没有任何性能差异。
当没有好处时,请勿使用CDI或EJB。当你开始需要注入、事件、拦截器、装饰器、生命周期跟踪等内容时,请添加CDI。这大多数情况下都适用。
除了这些基础知识外,如果你想要使用一些有用的容器服务,你只有在将CDI bean添加为EJB(通过添加@Stateful
、@Stateless
或@Singleton
)时才有这个选项。
以下是我使用EJB的短列表。
暴露一个JAX-WS @WebService
。我很懒。当@WebService
也是EJB时,你不必将其列出并在web.xml
文件中进行映射。这对我来说是一项工作。此外,我还可以使用下面提到的任何其他功能选项。所以这对我来说是一个明智的选择。
仅限于@Stateless
和@Singleton
使用。
通过@Path
公开一个JAX-RS资源。我还是很懒。当RESTful服务也是EJB时,你再次获得自动发现,并且不必将其添加到JAX-RS的Application
子类中或执行其他任何操作。此外,如果需要的话,我还可以将完全相同的bean公开为@WebService
或使用下面提到的任何一种伟大的功能。
仅限于@Stateless
和@Singleton
使用。
通过@Startup
实现启动时的加载。在CDI中目前没有与此相当的功能。容器生命周期中似乎漏掉了添加类似于AfterStartup
事件的内容。如果我们这样做了,你只需要有一个监听该事件的@ApplicationScoped
bean,它将有效地与@Singleton
和@Startup
相同。这已列入CDI 1.1的待办事项列表。
仅适用于@Singleton
。
@Asynchronous
方法调用。在任何服务器端环境中,开启线程都是不可取的。太多线程会严重降低性能。该注释允许您使用容器的线程池并行执行任务。这很棒。
适用于@Stateful
、@Stateless
和@Singleton
。
@Schedule
或ScheduleExpression
基本上是cron或Quartz
功能。同样非常棒。大多数容器在内部使用Quartz来实现这一点。然而,大多数人不知道,在Java EE中进行计划工作是事务性的!如果您更新数据库并计划一些工作,并且其中一个失败,则两者都将自动清除。如果EntityManager
的持久化调用失败或刷新存在问题,则无需取消计划工作。太好了,有事务支持。
仅适用于@Stateless
和@Singleton
。
上述关于事务的说明当然需要您使用JTA管理的EntityManager
。您可以在普通的“CDI”中使用它们,但是没有容器管理的事务,重复UserTransaction
提交/回滚逻辑可能变得非常乏味。
适用于所有Java EE组件,包括CDI、JSF @ManagedBean
、@WebServlet
、@WebListener
、@WebFilter
等。然而,@TransactionAttribute
注释仅适用于@Stateful
、@Stateless
和@Singleton
。
EntityManager
EXTENDED
管理的EntityManager
允许您在JTA
事务之间保持EntityManager
打开状态并不会丢失缓存数据。对于正确的时间和地点来说是很好的功能。请负责任地使用:)
仅适用于@Stateful
。
当你需要同步时,@Lock(READ)
和 @Lock(WRITE)
注解非常棒。它允许你免费获得并发访问管理,省去了所有的 ReentrantReadWriteLock 管理。在同一篮子里还有 @AccessTimeout
,它允许你指定线程在放弃之前等待获取 bean 实例的时间。
仅适用于 @Singleton
bean。
如果你真的没有使用ejb 3.1的任何功能,那么答案很简单。但是,我猜你的问题表明你怀疑有一些你正在从中受益的ejb 3.1概念,而你并不知道它们。一个例子可能是容器可以保持一组slsb准备好被使用,这样jms和数据库连接就不必作为请求的一部分注入。