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