我只是开始一个CDI项目。在此项目中,将Beans2注入Beans1内。
但是Beans2具有创建文件的方法。此方法实例化File对象,如下所示:

new File('myPathFile');


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

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

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不是Inject。

最佳答案

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

08-05 05:47