【问题标题】:does this JSF pattern break dependency injection?这个 JSF 模式会破坏依赖注入吗?
【发布时间】:2011-10-04 17:09:29
【问题描述】:

我有一个 JSF2 项目(GlassFish 3.1 上的 Mojarra)。

我有一个 ViewScoped bean,它通过一个实用程序类引用服务,如下所示:

@ManagedBean
@ApplicationScoped
public static class ServicesUtil {
  @EJB
  UserService userService;
  @EJB
  EmailService emailService;
  /** getters/setters **/
}

@ManagedBean
@ViewScoped
public class UserHandler {
  public String method() {
     ServicesUtil.getUserService().doUserStuff();
     return "newPage";
  }
}

我的问题是,由于 ServicesUtil 是 ApplicationScoped,这是否意味着整个应用程序的每个服务只有一个实例?这是不好的做法吗?如果操作正确,GlassFish 中的 CDI 是否真的会根据需要创建新实例?

同样,如果将服务注入到 UserHandler 中,应用程序是否会更具可扩展性?

我们添加 ServicesUtil 层的原因是我的一位同事说,当它是 ViewScope 时,他偶尔会遇到让注入在 Handler 中工作的问题。在 ViewScoped bean 中使用 @EJB 会有什么困难吗?

非常感谢任何帮助!

罗伯

【问题讨论】:

    标签: jsf glassfish cdi


    【解决方案1】:

    您使用的模式似乎没有多大意义。将 EJB 注入到视图范围的 bean 中应该没有问题。

    根据您使用的 EJB 的类型(无状态、有状态或单例),情况会有所不同。

    如果 userService 和 emailService 是无状态的(它们很可能应该是),那么使用首先注入应用程序范围 bean 的 bean 将一无所获。也就是说,注入的不是 bean 本身,而是一个代理,并且对它的每个请求都会路由到不同的真实 bean 实例(请参阅http://en.wikipedia.org/wiki/Enterprise_JavaBean#Stateless_Session_Beans)。

    如果 userService 和 emailService 是有状态的,你会在这里得到一个实例,但我非常怀疑你需要在应用程序中的每个用户之间共享实际的实例。但即使您希望这样做,一次也只有一个用户(线程)可以访问有状态 bean。

    如果这些服务是单例的,您可以直接将它们注入到视图范围的 bean 中。绝对没有理由通过应用程序范围的 bean。

    此外,ServicesUtil.getUserService() 是一个静态方法,因此使用它来获取注入服务是脆弱的。如果你想使用这个(你不应该,但假设)ServicesUtil 应该被注入到UserHandler

    然后,您似乎混淆了 CDI 和 JSF 托管 bean。我同意这令人困惑,但目前就是这样。 @ViewScoped 不能与遇到的 CDI bean 组合使用。从您的代码中不清楚@ManagedBean 是JSF 变体还是Java EE/CDI 变体。在这种情况下,如果你想使用视图范围,它应该是javax.faces.bean.ManagedBean

    【讨论】:

    • 嗨——你能详细说明一下这个“@ViewScoped 不能与遇到 CDI bean 的组合”——我不明白你的意思。我目前正在使用 javax.faces.bean.ManagedBean 和 javax.ejb.EJB 注释。再次感谢!
    • 他的意思是当你使用javax.annotation.ManagedBean(或javax.inject.Named)时它不起作用。
    • 目前正在查看相同的模式。注入 viewscoped bean 会保持 ejb ref 并且如果服务器死掉并且会话故障转移到新的 jvm 将出错(如果 HA 不重要,则没有问题)。上面的模式是注入和服务定位器模式之间的一个很好的中间路径,即使用@EJB 注入应用程序,然后从请求/视图范围的 bean 中使用它们。
    猜你喜欢
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 2019-12-29
    • 2010-11-04
    • 1970-01-01
    • 2019-02-18
    • 2019-02-25
    • 1970-01-01
    相关资源
    最近更新 更多