【问题标题】:CDI injection of subclasses of session scoped beans as a managed propertyCDI 注入会话范围 bean 的子类作为托管属性
【发布时间】:2022-10-24 02:54:20
【问题描述】:

我正在使用 JSF 2.3,我想使用 CDI 将会话范围 bean 的不同子访问作为托管属性注入。

从下面的链接

How to inject different subclasses as ManagedProperty JSF 2?

我知道这对于使用“旧”JSF 和 JEE 注释的 RequestScoped bean 是不可能的,但是我的 bean 具有会话范围,并且我正在使用 CDI 注入,因此与上面链接中使用的注释不同。

特别是我有:

public abstract class BaseContainer {
     String prop1;
}

@Named
@SessionScoped
public class MaklerContainer extends BaseContainer {
     String prop 2;
}

@Named
@SessionScoped
public class  AppManagerContainer extends MaklerContainer {
     String prop 3;
}

public abstract class BaseBean {

   @Inject
   @javax.faces.annotation.ManagedProperty(value = "#{maklerSessionContainer}")
   private MaklerSessionContainer maklerSessionContainer;

}

是否可以将 MaklerContainer 和 AppManagerContainer 的可互换实例作为上面 BaseBean 类的托管属性 maklerSessionContainer 注入?

【问题讨论】:

  • 重要的问题是系统应该如何决定应该在注入点注入MaklerContainerAppManagerContainer 中的哪一个,例如@Inject MaklerContainer x。你有什么需求?
  • 这应该在登录时完成,具体取决于用户角色。

标签: java cdi managed-bean session-scope jsf-2.3


【解决方案1】:

让我描述一个选项,可能还有其他选项。

首先,如果你想注入不同的子访问,您必须找到一种方法来为 CDI 消除歧义,否则它会抱怨“不明确的依赖关系”。例如。鉴于问题的类层次结构,下面的行会导致模棱两可的依赖异常,因为 CDI 无法决定是注入 MaklerContainer 还是扩展它的 AppManagerContainer

@Inject MaklerContainer maklerContainer; // ambiguous!

您可以使用限定符、命名 bean 或 @Typed(也许还有更多方法)。

让我们使用@Named,因为它已经存在。

这个想法是创建一个生产者,将MaklerContainer 类型的第三个bean(具有不同的名称)引入适当的范围。生产者代码将决定在运行时选择 2 个实现中的哪一个。像这样的东西:

@ApplicationScoped
public class TheProducer {
  @Inject @Named("maklerContainer")
  private MaklerContainer maklerContainer;
  @Inject @Named("appManagerContainer")
  private AppManagerContainer appManagerContainer;
  @Inject
  private User currentUser;

  @Produces
  @SessionScoped
  @Named("theOne") // choose appropriate name of course
  public MaklerContainer makeMaklerContainer() {
    if (currentUser.hasRole("Role1")) {
      return appManagerContainer;
    } else {
      return maklerContainer;
    }
  }
}

现在您所要做的就是注入适当的名为MaklerContainer,例如:

@Inject @Named("theOne") MaklerContainer maklerContainer;

【讨论】:

  • 好,很好。然后我会在我的 BaseBean 中注入 TheProducer Bean 还是什么?谢谢!
  • 不,只需注入MaklerContainer。我会更新答案,这部分显然是缺失的。
猜你喜欢
  • 2012-06-27
  • 1970-01-01
  • 2014-06-30
  • 2013-12-12
  • 2013-09-24
  • 2012-12-26
  • 1970-01-01
  • 2023-03-30
  • 2012-01-20
相关资源
最近更新 更多