1

我刚开始一个CDI项目。在这个项目中,一个 Beans2 被注入到一个 Beans1 中。但是 Beans2 有一个创建文件的方法。此方法像这样实例化文件对象:

new File('myPathFile');

因为这个实例化不是由 CDI 容器管理的,所以 Bean2 没有注入到 Beans1 中。我尝试让生产者将文件注入到 Beans2 中,但我是否需要为我将使用的所有 java 基类做同样的事情?

是否有另一种解决方案可以简单地使用不需要注入的类?

豆1:

@Dependant
public class Bean1 implements Serializable {
    private @Inject @Bean2Producer Bean2 bean2;

    public void someMethod() {
        bean2.foo();
    }
}

豆2:

@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() 方法中调用 new File,则 PathDir 不是 Inject。

4

1 回答 1

2

Bean2 没有注入到 Bean1 中的原因是 Bean2 中没有合适的构造函数让 CDI 可以自动创建它的实例。Bean 需要有一个不带参数的构造函数或一个注入所有参数的构造函数,请参阅Java EE 教程中的更多内容

这就是 CDI 的简单限制。如果要将参数传递给 bean,则需要在 bean2 注入后提供一个 setter 方法来传递参数。或者,如果您需要在对象创建期间拥有一些值(因为抽象父级需要它们),您需要注入所有构造函数参数,如下所示(@Param1并且@param2是限定符):

public Bean2(@Inject @Param1 String param1, @Inject @Param2 boolean param2) {
     super(param1, param2);
}

或者,您不需要将每个对象都转换为 CDI bean,尤其是当您对构造函数参数有要求时。您可以在创建 bean 后手动注入所有依赖项。这意味着你确实@Inject在 Bean2 中使用,但提供了一个 setter 方法,注入到 bean1 并在 bean1 的 postconstruct 方法中设置值,示例如下:

豆1:

@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
    }
}

豆2:

@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 必需的依赖项。

于 2015-09-10T15:14:45.753 回答