CDI с неуправляемыми объектами - PullRequest
7 голосов
/ 01 февраля 2011

Предположим, у меня есть два класса, первый класс без каких-либо свойств, полей или аннотаций:

public class B {}

И класс, которому вводится B, например:

public class A {
    @Inject
    private B b;

    public B getB() {
        return b;
    }
}

Теперь класс A довольно бесполезен, пока мы его не используем, поэтому есть два варианта:

  • @ Inject it
  • Создайте его вручную, используя верный "new A ()"

Если A вводится, CDI управляет им и достаточно любезен, чтобы ввести B, который имеет неявную область действия @Dependent.Круто, именно то, что я хочу.

Однако, если я создаю вручную A (скажем, на фабрике или в сборщике), CDI полностью игнорирует мой объект и не вводит объект типа B.

Пример, о котором я говорю, когда он не работает, здесь объект a всегда будет оставаться нулевым:

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 является допустимым управляемым компонентом и имеет допустимую область действия, точно так же как класс B. Даже если я добавлю @Producer к статическому методу, он ничего не изменит (что хорошо, вызывает идеюстатический метод должен вызывать его, а не вводить Builder в любом месте).

1 Ответ

9 голосов
/ 02 февраля 2011

Инъекция зависимости, хотя и полезна, но не волшебна.DI работает так, что когда вы запрашиваете у контейнера экземпляр объекта, контейнер сначала создает его (через new()), а затем устанавливает зависимости (как это происходит, зависит от вашей среды).

Есливы создаете сущность самостоятельно, тогда контейнер не имеет представления, что вы сконструировали сущность и не можете установить зависимости сущности.

Если вы хотите использовать фабрику, то в большинстве сред есть какой-то способ настройкиобъект, так что контейнер знает, чтобы сделать статический вызов метода фабрики и не вызывать конструктор объекта.Однако вам все равно нужно получить свою сущность из контейнера.

Редактировать: Этот сайт , кажется, демонстрирует, как использовать фабрику в CDI.

...