【问题标题】:Do i need to make all object instantiation via producer in CDI我是否需要通过 CDI 中的生产者进行所有对象实例化
【发布时间】:2015-12-05 06:40:03
【问题描述】:

我刚刚开始了一个 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。

【问题讨论】:

  • 不,你不需要让所有东西都可以注射。我建议您阅读一些文档和教程,以便您真正了解使用依赖注入时您在做什么,以及最重要的是为什么
  • 我阅读了 Weld 文档和教程,但我不明白为什么当一切都不可注射时注射失败。
  • 没有看到更多的代码,就不可能说出为什么事情不工作。
  • 对不起,经过一些测试,它出现 pathDir,从不注入。你知道为什么吗?它正确地注入了另一个 bean
  • 您仍然没有显示pathDir 的值将在哪里产生。你真的了解 CDI 的工作原理吗?

标签: java cdi weld-se


【解决方案1】:

没有将Bean2注入到Bean1中的原因是Bean2中没有合适的构造函数,CDI可以自动创建它的实例。 Beans 需要有一个没有参数的构造函数或一个注入所有参数的构造函数,更多信息请参见 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方法中设置值,示例如下:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    相关资源
    最近更新 更多