我是否需要通过 CDI 中的生产者进行所有对象实例化
Do i need to make all object instantiation via producer in CDI
我刚刚开始一个 CDI 项目。在这个项目中,Beans2 被注入到 Beans1 中。
但是 Beans2 有一个创建文件的方法。此方法像这样实例化文件对象:
new File('myPathFile');
因为这个实例化不是由 CDI 容器管理的,所以 Bean2 没有注入到 Beans1 中。我试图让生产者将文件注入 Beans2,但我是否需要对我将使用的所有 java 基础 class 做同样的事情?
是否有另一种解决方案可以简单地使用不需要注入的 class?
Bean1:
@Dependant
public class Bean1 implements Serializable {
private @Inject @Bean2Producer Bean2 bean2;
public void someMethod() {
bean2.foo();
}
}
Bean2 :
@Dependant
public class Bean2 extends AbstractClass implements Serializable {
private @Inject @PathDir String pathDir;
public Bean2(String param1, boolean param2) {
super(param1, param2);
}
public void foo() {
File file = new File(pathDir);
}
}
pathDir 生产者:
@ApplicationScoped
public class ProjectProducer implements Serializable {
@Produces
@PathDir
public String getPathDir() {
try {
return PropsUtils.geetProperties().getProperty(PATH_DIR);
} catch (Exception e) {
e.printStackTrace();
}
}
}
PathDir 注释:
@Qualifier
@Target({FIELD, METHOD, PARAMETER, CONSTRUCTOR, TYPE})
@Retention(RUNTIME)
@Documented
public @interface PathDir {}
在此示例中,如果在 foo() 方法中调用新文件,则 PathDir 不会注入。
Bean2没有注入Bean1的原因是Bean2中没有合适的构造函数,CDI可以自动创建它的实例。 Bean 需要有一个不带参数的构造函数或一个注入所有参数的构造函数,请参阅 Java EE tutorial
这很简单,就是 CDI 的 限制。如果你想将参数传递给你的 bean,你需要提供一个 setter 方法来在注入 bean2 之后传递参数。或者,如果在对象创建期间需要一些值(因为抽象父级需要它们),则需要注入所有构造函数参数,如下所示(@Param1
和 @param2
是限定符):
public Bean2(@Inject @Param1 String param1, @Inject @Param2 boolean param2) {
super(param1, param2);
}
或者,您不需要将每个对象都变成一个CDI bean,尤其是当您对构造函数参数有要求时。您可以在创建 bean 后手动注入所有依赖项。也就是说你在Bean2中使用了@Inject
,但是提供了一个setter方法,注入到bean1中,在bean1的postconstruct方法中设置值,例子如下:
Bean1 :
@Dependant
public class Bean1 implements Serializable {
private @Inject @PathDir String pathDir; // inject pathDir here instead of in Bean2
private Bean2 bean2; // without inject, created in init()
@PostConstruct
public void init() {
bean2 = new Bean2("param1", "param2");
bean2.setPathDir(pathDir); // set injected value manually
}
public void someMethod() {
bean2.foo(); // here bean2.pathDir should be already initialized via setPathDir in init() method above
}
}
Bean2 :
@Dependant
public class Bean2 extends AbstractClass implements Serializable {
private String pathDir;
public Bean2(String param1, boolean param2) {
super(param1, param2);
}
public void setPathDir(String pathDir) {
this.pathDir = pathDir;
}
public void foo() {
File file = new File(pathDir);
}
}
或者甚至更好,合并 setPathDir 和 Bean2 构造函数 - 很明显 pathDir 是 Bean2 的必需依赖项。
我刚刚开始一个 CDI 项目。在这个项目中,Beans2 被注入到 Beans1 中。 但是 Beans2 有一个创建文件的方法。此方法像这样实例化文件对象:
new File('myPathFile');
因为这个实例化不是由 CDI 容器管理的,所以 Bean2 没有注入到 Beans1 中。我试图让生产者将文件注入 Beans2,但我是否需要对我将使用的所有 java 基础 class 做同样的事情?
是否有另一种解决方案可以简单地使用不需要注入的 class?
Bean1:
@Dependant
public class Bean1 implements Serializable {
private @Inject @Bean2Producer Bean2 bean2;
public void someMethod() {
bean2.foo();
}
}
Bean2 :
@Dependant
public class Bean2 extends AbstractClass implements Serializable {
private @Inject @PathDir String pathDir;
public Bean2(String param1, boolean param2) {
super(param1, param2);
}
public void foo() {
File file = new File(pathDir);
}
}
pathDir 生产者:
@ApplicationScoped
public class ProjectProducer implements Serializable {
@Produces
@PathDir
public String getPathDir() {
try {
return PropsUtils.geetProperties().getProperty(PATH_DIR);
} catch (Exception e) {
e.printStackTrace();
}
}
}
PathDir 注释:
@Qualifier
@Target({FIELD, METHOD, PARAMETER, CONSTRUCTOR, TYPE})
@Retention(RUNTIME)
@Documented
public @interface PathDir {}
在此示例中,如果在 foo() 方法中调用新文件,则 PathDir 不会注入。
Bean2没有注入Bean1的原因是Bean2中没有合适的构造函数,CDI可以自动创建它的实例。 Bean 需要有一个不带参数的构造函数或一个注入所有参数的构造函数,请参阅 Java EE tutorial
这很简单,就是 CDI 的 限制。如果你想将参数传递给你的 bean,你需要提供一个 setter 方法来在注入 bean2 之后传递参数。或者,如果在对象创建期间需要一些值(因为抽象父级需要它们),则需要注入所有构造函数参数,如下所示(@Param1
和 @param2
是限定符):
public Bean2(@Inject @Param1 String param1, @Inject @Param2 boolean param2) {
super(param1, param2);
}
或者,您不需要将每个对象都变成一个CDI bean,尤其是当您对构造函数参数有要求时。您可以在创建 bean 后手动注入所有依赖项。也就是说你在Bean2中使用了@Inject
,但是提供了一个setter方法,注入到bean1中,在bean1的postconstruct方法中设置值,例子如下:
Bean1 :
@Dependant
public class Bean1 implements Serializable {
private @Inject @PathDir String pathDir; // inject pathDir here instead of in Bean2
private Bean2 bean2; // without inject, created in init()
@PostConstruct
public void init() {
bean2 = new Bean2("param1", "param2");
bean2.setPathDir(pathDir); // set injected value manually
}
public void someMethod() {
bean2.foo(); // here bean2.pathDir should be already initialized via setPathDir in init() method above
}
}
Bean2 :
@Dependant
public class Bean2 extends AbstractClass implements Serializable {
private String pathDir;
public Bean2(String param1, boolean param2) {
super(param1, param2);
}
public void setPathDir(String pathDir) {
this.pathDir = pathDir;
}
public void foo() {
File file = new File(pathDir);
}
}
或者甚至更好,合并 setPathDir 和 Bean2 构造函数 - 很明显 pathDir 是 Bean2 的必需依赖项。