具有缓存的EJB服务定位器

时间:2013-10-22 15:41:30

标签: java java-ee ejb service-locator

我正在使用Service Locator实现来缓存javax.naming.Context#lookup调用的结果,并将其映射到请求的EJB接口,因此所有后续请求(对于同一个EJB)在第一个之后返回缓存的实例

我担心的是:

  1. 由于使用了相同的实例,因此没有使用 服务器EJB池,它将为多个同时请求提供服务 使用多个EJB(除非底层服务器逻辑以某种方式产生 使用EJB池)
  2. 无状态和有状态EJB是线程安全的,但从那以后, 每个EJB类只使用一个实例,EJB具有EntityManager 通过@PersistenceContext注入,我认为这意味着多个 线程可以使用相同的EntityManager实例(不仅仅是 持久化上下文),绝对不是线程安全的
  3. 您是否认为最好不要在服务定位器中使用缓存,或者我的担忧在EJB行为方面是不合理的?

1 个答案:

答案 0 :(得分:5)

从查找操作(通过JNDI服务)获得的是一个名为Stub的对象,并且他没有使用任何特殊的EJB实例修复。

缓存后,每次调用EJB服务时,存根都可以从池中选择不同的EJB实例(这适用于无状态);即使在集群环境中,存根对象也能够从不同的服务器中选择一个EJB实例。

因此,缓存存根对象应该不是问题。

请注意,我说的是无状态,我认为缓存对statefull会话bean没有意义。

EJB查找是一项耗时的操作,因此缓存可以提高客户端的性能。


关于您的评论:

如果你在一个由多个并发线程(如Servlet)使用的组件中使用EntityManager,是的,你将不得不关心并发性,但EJB的Tread模型暗示不会是几个线程使用相同的EntityManager实例同时,因此EM不是线程安全的事实并不重要。

  

我还担心的是,不同的EJB正在使用   注入(通过@PersistenceContext)EntityManager实例

我认为对于简单的风景来说,最好的方式是考虑它,如果描述为here

  

多用户客户端/服务器应用程序中最常见的模式是   EntityManager的每次请求。在此模型中,来自客户端的请求是   发送到服务器(运行JPA持久层的地方),一个新的   打开EntityManager,执行所有数据库操作   这个工作单位。一旦工作完成(和响应   对于已经准备好的客户端),持久化上下文被刷新   并关闭,以及实体管理器对象。

这将更难检查;)