CDI具有非托管对象

问题描述:

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

Suppose that I have two classes, first a class without any properties, fields or annotations:

public class B {}

还有一个获得B注入的类,如下所示:

And a class which gets B injected, like this:

public class A {
    @Inject
    private B b;

    public B getB() {
        return b;
    }
}

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

Now class A is pretty useless until we use it, so there are two options:


  • @Inject it

  • 使用可靠的手动构建它新的A()

如果A被注入,CDI管理它并且足够注入B,其隐含范围为@相关。很酷,正是我想要的。

If A gets injected, CDI manages it and is kind enough to inject B which has the implicit scope of @Dependent. Cool, just what I want.

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

However, if I manually construct A (let's say in a factory or a builder), CDI completely ignores my object and won't inject an object of type B.

示例我在谈论它何时不起作用,此处对象a将始终保持为空:

Example I'm talking about when it doesn't work, here object a will always remain 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
    }
}

为什么这不起作用?

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

Class A is a valid managed bean and has a valid scope, just like class B. Even if I add @Producer to the static method, it won't change anything (which is fine, cause the idea of the static method is to call it, not to inject Builder anywhere).

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

Dependency injection, while useful, is not magical. The way DI works is that when you ask the container for an instance of an object the container first constructs it (via new()) and then sets the dependencies (how this happens depends on your framework).

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

If you construct the entity yourself then the container has no idea you've constructed the entity and can't set the dependencies of the entity.

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

If you want to use a factory then most frameworks have some way of configuring the entity so that the container knows to make a static factory method call and not call the constructor of the entity. However, you still have to obtain your entity from the container.

编辑:此网站似乎演示了如何在CDI中使用工厂。

This site seems to demonstrate how to use a factory in CDI.