依赖注入和容器类(JavaEE7)

依赖注入和容器类(JavaEE7),java,containers,cdi,java-ee-7,inject,Java,Containers,Cdi,Java Ee 7,Inject,我是DI新手,但突然我需要在EJB应用程序中使用它,所以我尝试重新制作它 该方法包括具有2个字段的容器类-2个实现。它根据参数与一个或两个实现一起工作。容器是在singleton的方法调用中创建的,但被其他ejb bean使用 这里我需要帮助-如何使SecurityContainer类与其他CDI管理的类(ejb bean)正常工作,或者成为CDI管理的类本身 我给出了一个旧的(非CDI)代码,它是如何工作的。读取参数并实例化容器: @Singleton public class MySingl

我是DI新手,但突然我需要在EJB应用程序中使用它,所以我尝试重新制作它

该方法包括具有2个字段的容器类-2个实现。它根据参数与一个或两个实现一起工作。容器是在singleton的方法调用中创建的,但被其他ejb bean使用

这里我需要帮助-如何使SecurityContainer类与其他CDI管理的类(ejb bean)正常工作,或者成为CDI管理的类本身

我给出了一个旧的(非CDI)代码,它是如何工作的。读取参数并实例化容器:

@Singleton
public class MySingleton {
    private static final MySingleton instance = new MySingleton();
    private volatile SecurityHelper securityHelper;  // container
    public void setSecurityHelper(SecurityHelper secHelper){ securityHelper=secHelper; }
    public SecurityHelper getSecurityHelper(){ return securityHelper; }     
    /* now it has some @Inject....*/    

    public void start(String passwordP, String passwordH)
          .....
        // application work with one or two implementations of security
        if ("P".equals(DbParams.getServerSecurityFlag()))
            instance.setSecurityHelper(new SecurityContainer(new SecurityHelperImplP(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()), 
                                null));             
        else 
            instance.setSecurityHelper( new SecurityContainer( new SecurityHelperImplP(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()), 
                                new SecurityHelperImplH(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()) ) );
        securityHelper.createSecurity(passwordP, passwordH);
以下是容器类:

public class SecurityContainer implements SecurityHelper {
    private SecurityHelper secPrg;
    private SecurityHelper secHard;
    public SecurityContainer(SecurityHelper secPrg, SecurityHelper secHard){
        this.secPrg=secPrg;
        this.secHard=secHard;
    }
具体的实现现在必须注入DbWorker和ResponseBuilderEJB bean。SecurityHelperImplH看起来是一样的

public class SecurityHelperImplP implements SecurityHelper {
    private SecurityPrg securityPrg = null;

    private DbWorker ora;           // now they are CDI managed
    private ResponseBuilder builder; 

    public SecurityHelperImplP(DbWorker dbworker, ResponseBuilder bld){
        this.ora = dbworker;
        this.builder = bld;
    }

我相信我需要资格证书,也许还需要一个制作人,但从外观上看,我无法将这些点连接起来,你可以选择任何一种方式-制作人或资格证书。这两种方法都需要一些重构,对我来说,producer似乎是一种更平滑的方法。 它将允许您检查参数并根据您的需要定制生产者对象(
SecurityContainer

首先,您的
SecurityContainer
字段需要是注入点,因此添加
@Inject

@Inject
private volatile SecurityHelper securityHelper;  // container
注意:记住删除setter方法,当使用CDI时,您不需要它

至于我们如何生产它。你的开始工作基本上已经完成了!您所需要的只是让它成为一个生产者,设置正确的返回类型,并确保将参数设置到位。因此,一步一步:

1) 生产者方法参数

生产商方法的所有参数都自动视为另一个可注入源。例如,您将能够
@注入字符串密码p
)。哎哟,这不会马上起作用,我不知道如何准确地检索这些参数

2) 生产方法如何运作

它是CDI每次需要创建实例时调用的方法。因此,您必须决定
SecurityHelper
范围。由于这是在
@Singleton
的start方法中设置一次的,所以我认为它在运行时不会改变。在这种情况下,您可能需要对
@ApplicationScoped

3) 那一切看起来怎么样

假设我没有误解,下面是一段代码,它可以实现您想要的功能:

@Produces  // telling CDI this is how it is supposed to create instances of this type
@ApplicationScoped // what scope does the produced bean have?
public SecurityHelper produceSecHelper() {
  // TODO add logic to retrieve these params!
  String passwordP;
  String passwordH;

  SecurityHelper result;
  // application work with one or two implementations of security
  if ("P".equals(DbParams.getServerSecurityFlag()){
      result = new SecurityContainer(new SecurityHelperImplP(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()), 
                                null); 
  } else {
      result = new SecurityContainer( new SecurityHelperImplP(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()), 
                                new SecurityHelperImplH(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()));
  }
  result.createSecurity(passwordP, passwordH);
  return result;
}

注意:CDI将自动调用此方法。您不应该手动执行此操作,即使您执行了此操作,CDI也不会识别它。

从外观上看,您可以选择生产者或限定符。这两种方法都需要一些重构,对我来说,producer似乎是一种更平滑的方法。 它将允许您检查参数并根据您的需要定制生产者对象(
SecurityContainer

首先,您的
SecurityContainer
字段需要是注入点,因此添加
@Inject

@Inject
private volatile SecurityHelper securityHelper;  // container
注意:记住删除setter方法,当使用CDI时,您不需要它

至于我们如何生产它。你的开始工作基本上已经完成了!您所需要的只是让它成为一个生产者,设置正确的返回类型,并确保将参数设置到位。因此,一步一步:

1) 生产者方法参数

生产商方法的所有参数都自动视为另一个可注入源。例如,您将能够
@注入字符串密码p
)。哎哟,这不会马上起作用,我不知道如何准确地检索这些参数

2) 生产方法如何运作

它是CDI每次需要创建实例时调用的方法。因此,您必须决定
SecurityHelper
范围。由于这是在
@Singleton
的start方法中设置一次的,所以我认为它在运行时不会改变。在这种情况下,您可能需要对
@ApplicationScoped

3) 那一切看起来怎么样

假设我没有误解,下面是一段代码,它可以实现您想要的功能:

@Produces  // telling CDI this is how it is supposed to create instances of this type
@ApplicationScoped // what scope does the produced bean have?
public SecurityHelper produceSecHelper() {
  // TODO add logic to retrieve these params!
  String passwordP;
  String passwordH;

  SecurityHelper result;
  // application work with one or two implementations of security
  if ("P".equals(DbParams.getServerSecurityFlag()){
      result = new SecurityContainer(new SecurityHelperImplP(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()), 
                                null); 
  } else {
      result = new SecurityContainer( new SecurityHelperImplP(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()), 
                                new SecurityHelperImplH(DbWorkerImpl.getInstance(), ResponseBuilderImpl.getInstance()));
  }
  result.createSecurity(passwordP, passwordH);
  return result;
}

注意:CDI将自动调用此方法。您不应该手动执行此操作,即使执行了此操作,CDI也不会识别它。

您应该将此生产者放在哪里?现在我离开了SecurityContainer。MySingleton现在是CDI托管的,其他托管bean使用MySingleton getSecurityHelper()中的securityContainer。只要生产者驻留在另一个CDI bean中(以便CDI能够找到它),这并不重要。根据CDI 1.2规范-
生产者方法必须是托管bean类或会话bean类的默认访问、公共、受保护或私有、非抽象方法所以我说,把它放在方便的地方。我是否应该将SecurityHelperImplP和SecurityHelperImplH作为参数传递给生产者?我试图用限定符传递它们,但是得到编译错误如果你想把它们作为参数,你需要为它们都有一个生产者,用限定符,因为它们都是相同类型(字符串)。我想你有。我不知道你的编译错误是什么。但由于它是编译的,所以您做了一些错误的事情,而您的IDE通常会告诉您发生了什么。您应该将这个生产者放在哪里?现在我离开了SecurityContainer。MySingleton现在是CDI托管的,其他托管bean使用MySingleton getSecurityHelper()中的securityContainer。只要生产者驻留在另一个CDI bean中(以便CDI能够找到它),这并不重要。根据CDI 1.2规范-
生产者方法必须是托管bean类或会话bean类的默认访问、公共、受保护或私有、非抽象方法所以我说,把它放在方便的地方。我是否应该将SecurityHelperImplP和SecurityHelperImplH作为参数传递给生产者?我试过了