5

我有一个与使用 @EJB 注释时可能的性能问题有关的问题。想象以下场景

public class MyBean1 implements MyBean1Remote{
 @EJB
 private MyBean2Remote myBean2;
 @EJB
 private MyBean2Remote myBean3;
 ...
 @EJB
 private MyBean20Remote myBean20;
}  

有一个 bean 与其他 bean 有许多依赖关系。根据 EJB 规范,如果我想将 MyBean1Remote 注入到其他某个 bean,容器必须从其池中获取所有必需的依赖项,然后将其注入 MyBean1Remote,然后注入对 MyBean1Remote 存根的引用。

因此在以下场景中容器需要保留 20 个 ejb(myBean1 及其 19 个依赖项)

public class MyAnotherBean implement MyAnotherRemote{
  @EJB
  private MyBean1Remote myBean1
}

假设在大多数情况下,我们将为 myBean1 的每个业务方法仅使用一个依赖项。因此,每次我们想要注入该 bean 时,我们都会强制容器保留许多不必要的 EJB。让我们还假设我们正在对远程 bean 进行操作,因此容器可能还需要在注入依赖 bean 之前执行一些负载平衡算法。

问题:

  1. 在集群环境中运行时,这不会导致不必要的资源预留和更多的性能问题吗?

  2. 也许好的旧 ServiceLocator 可能是更好的解决方案,因为使用这种方法,我们会在真正需要时要求特定的 EJB?

4

2 回答 2

12

容器不注入 EJB 的实例;它注入实现所需接口的轻量级容器生成的代理对象的实例。

public class MyBean1 implements MyBean1Remote {
   ...
}

public class MyAnotherBean implement MyAnotherRemote {
   @EJB
   private MyBean1Remote myBean1;
}

在您的示例中,MyAnotherBean.myBean1 将被注入一个实现 MyBean1Remote 接口的代理对象。

假设一个无状态会话 bean(因为你提到了池),容器不会从方法就绪池中分配一个实际的 EJB 实例,直到在代理上调用一个方法,并且在代理方法调用返回之前将实例返回到池中.

于 2011-01-22T08:06:46.313 回答
5

在大多数情况下,尤其是在使用无状态会话 bean 时,您的 bean 实例将被池化。池化背后的基本原理之一是依赖注入查找可能相对昂贵,因此 bean与所有已注入的依赖项(存根)一起池化。

因此,每次调用 on 方法时MyAnotherBean,都不会创建具有 20 个传递依赖项的 bean,并动态解决所有这些依赖项。相反,从池中选择一个完全实例化的实例,然后将方法调用定向到该实例。

另请注意,除非您正在执行 JNDI 联合,否则您通常无法轻松地注入远程 EJB。

于 2011-01-22T00:23:58.420 回答