Guice: последствия внедрения поля

Мое понимание Guice заключается в следующем:

  • Инъекция на уровне конструктора (@Inject public class Widget(Dep one, Dep two)) подразумевает, что Guice всегда будет вводить этот конструктор каждый раз, когда он вызывается через Injector; и
  • Ввод уровня метода (@Inject public void setDepOne(Dep one)) подразумевает, что Guice всегда будет вводить этот метод всякий раз, когда он вызывается, пока объект Widget был создан с помощью Guice Injector

Правильны ли эти два предположения? Если нет, уточните!

Итак, что я повесил трубку: каковы последствия внедрения на уровне поля?

@Inject private Dep one;

Означает ли это, что Guice всегда будет вводить свойство, когда объект создается через инжектор Guice? В этом случае я предполагаю, что он конфликтует с инъекцией на уровне конструктора.

Например, вызывает ли конфликт/ошибку следующее:

public class Widget {
    @Inject private Dep one;

    private Dep two;

    // Dep one already injected as a field!
    @Inject public Widget(Dep one, Dep two) {
        // ...
    }
}

Спасибо заранее!

Ответ 1

Guice всегда будет вводить все поля, методы и любой отдельный конструктор, аннотированный с помощью @Inject. Имейте в виду, что конструктор всегда вводится первым, поэтому ваше аннотированное поле фактически перезапишет эту инъекцию. Возьмите этот модифицированный пример:

class Widget {
    @Inject
    private Dep one;

    @Inject
    public Widget(Dep one) {
        this.one = one;
        System.out.println(one);
    }

    public void printDependency() {
        System.out.println(one);
    }
}

class Dep {}

public class MyMain {
    public static void main(String[] args) {
        Injector i = Guice.createInjector();
        i.getInstance(Widget.class).printDependency();

    }
}

При запуске это приведет к примерно так:

[email protected]
[email protected]

Ясно, что два разных объекта. Первая строка - это конструктор; вторая - инъекция поля.

Я не часто нашел применение для инъекций в поле, за исключением того, чтобы уменьшить многословность при написании образцов кода Guice. В производственном коде это неразумно, потому что это затрудняет проверку кода.

Ответ 2

Ваши предположения верны. Я считаю, что в этом конкретном случае Guice дважды вводит one - один раз через конструктор, один раз через поле - если ничего другого, потому что он не может знать, что они идут в одно и то же поле.