【问题标题】:Create only objects used in Java EE仅创建 Java EE 中使用的对象
【发布时间】:2019-02-23 13:41:43
【问题描述】:

鉴于下面的 EJB,容器是否足够智能以仅创建使用的对象?

@Stateless
public class MyBean {

   @EJB
   Clazz1 obj1;

   @EJB
   Clazz2 obj2;

   public void run(int x) {

     if (x == 1)
         obj1.printCode();
     else
         obj2.printCode();

   }
 }

【问题讨论】:

  • 错误,它们都被使用了。构造 MyBean 时会注入 obj1 和 obj2。然后每次调用 run() 时都会调用 obj1 或 obj2,这可能是很多次。
  • 假设注入了几十个类,多次构造bean,有没有设计模式,比如工厂,可以用来处理这种场景?
  • 您已经在使用一种设计模式:依赖注入。看起来你很关心性能,但是注入几十个对象不会导致任何性能问题。如果你真的在一个 bean 中注入了几十个依赖项,你真的应该关心设计和可维护性。一个拥有几十个不同依赖项的 bean 显然有太多的责任。

标签: java jakarta-ee ejb cdi java-ee-8


【解决方案1】:

容器必须在实例化 bean 本身之前解析 bean 的所有依赖项(首先实例化它们)。

现在当你调用一个方法时真正发生的事情可能会有所不同...... 您在这里使用的是纯 EJB,您的代码中没有任何 CDI 斑点! @EJB 是用于依赖注入的 EJB 注释,@Stateless 是用于“范围”的 EJB 注释。

如果您要使用 CDI 并将 Weld 作为其实现(除了 tomee 之外的所有 EE 服务器),那么您将获得任何普通范围 bean 的延迟实例化。这意味着您实际上注入了一个“空”代理对象,它只会在第一次访问时被实例化。

现在,我所说的 CDI 注入是什么意思 - 使用 @Inject 而不是 @EJB。 你仍然可以拥有你的 bean @Stateless,CDI,如果它在你的应用程序中运行,然后用它自己的范围包装它。 我还说您需要普通范围的 bean - 这意味着使用代理的 bean。 除了@Dependent,这些几乎都是CDI 范围。因此它是@RequestScoped@SessionScoped@ApplicationScoped。您的 bean 的依赖项必须具有这些范围才能实现惰性初始化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-27
    • 2014-04-14
    • 2015-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多