CDI具有非托管对象

Myt*_*ica 7 java java-ee cdi

假设我有两个类,首先是一个没有任何属性,字段或注释的类:

public class B {}
Run Code Online (Sandbox Code Playgroud)

和一个注入B的类,如下所示:

public class A {
    @Inject
    private B b;

    public B getB() {
        return b;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在A级在我们使用之前是没用的,所以有两种选择:

  • @Inject它
  • 使用可靠的"新A()"手动构造它

如果A被注入,CDI管理它并且足够注入B,其具有隐含的@Dependent范围.很酷,就是我想要的.

但是,如果我手动构造A(假设在工厂或构建器中),CDI完全忽略我的对象并且不会注入类型B的对象.

示例我在谈论它什么时候不起作用,这里对象a将始终保持为null:

public class Builder {
    @Inject
    private A a;

    public static Builder ofTypeSomething() {
        // do some magic here
        return new Builder();
    }

    private Builder() {
        // and some more here
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?

A类是一个有效的托管bean,并且有一个有效的范围,就像B类一样.即使我将@Producer添加到静态方法,它也不会改变任何东西(这很好,因为静态方法的想法是调用它,不要在任何地方注入Builder).

Pac*_*ace 9

依赖注入虽然有用,但并不神奇.DI工作的方式是当你向容器询问一个对象的实例时,容器首先构造它(via new())然后设置依赖项(这种情况发生的方式取决于你的框架).

如果您自己构造实体,那么容器不知道您构造了实体并且无法设置实体的依赖关系.

如果您想使用工厂,那么大多数框架都有一些配置实体的方法,以便容器知道进行静态工厂方法调用而不调用实体的构造函数.但是,您仍然必须从容器中获取实体.

编辑:这个网站似乎演示了如何在CDI中使用工厂.

  • 真正.但他们为什么不(DI容器供应商)让DI"神奇"?!?它肯定是可行的(例如,使用`ClassFileTransformer`). (2认同)