guice - поставщик возвращает всегда тот же экземпляр

Я работаю с guice 3 и guice-servlet 3. В модуле я определил привязки такого типа:

[...]
bind(View.class).annotatedWith(Names.named("view1")).to(View1Impl.class);
bind(View.class).annotatedWith(Names.named("view2")).to(View2Impl.class);
[...]

В введенном классе View1Impl I определяется следующее:

public class View1Impl {

    @Inject @Named("view1") Provider viewProvider;

    @Inject
    void init() {
        View viewA = viewProvider.get();
        View viewB = viewProvider.get();

        log.debug(viewA == viewB);
        log.debug(viewA == this);
    }

}

Оба оператора возвращают true. Но этого не должно быть.

Что я делаю не так?

1
nl ja de
@Danyel Нет конструктора, потому что мне не нужен конструктор. Экземпляр вводится. И провайдер тоже. см. code.google.com/p/google-guice/wiki/InjectingProviders Вы действительно знаете, что такое инъекция зависимости? Вы знакомы с guice?
добавлено автор Christian, источник
Это мой вопрос, потому что я думаю, что ложь должна быть возвращена. Но я вижу вашу точку, зайдя в бесконечный цикл. Я, может быть, решит свою проблему, не желая загружать представление. Возможно, guice делает обнаружение цикла.
добавлено автор Christian, источник
Где ваш конструктор, что делает метод get ?
добавлено автор Danyel, источник
Я, но ваш пример действительно странный. Вы рекурсивно вводите свой Provider . На самом деле вам повезло, что он возвращает тот же экземпляр (хотя это тоже немного странно), потому что иначе вы попадаете в бесконечный цикл. Когда вы пытаетесь: System.out.println (injector.getInstance (View.class) == injector.getInstance (View.class)); , false возвращается. Может быть, кто-то может объяснить.
добавлено автор Danyel, источник

2 ответы

Возможно, вы уже проверили это - вы указали привязки «сортировки», которые вы используете, но стоит дважды проверить, что в вашем незаправленном коде ни один из задействованных классов не скрытно аннотируется с помощью @Singleton или привязаны к области Singleton.class . Кроме того, убедитесь, что ни одно из ваших привязок не использует toInstance() , который, конечно же, всегда будет возвращать этот предварительно сконструированный экземпляр во всех случаях и фактически является привязкой singleton.

У нас был случай, когда мы рефакторировали метод bindView и, в конце концов, забыли, что мы установили его, чтобы всегда привязывать его аргумент как singleton (так, чтобы родительский контейнер представления и контроллер представления могли тот же взгляд).

Запрет на то, что, как указал Даньел, есть обнаружение круговой зависимости , закодированное в Guice, и поскольку вы вызываете свой provider.get() в @Inject - аннотированный метод, вы можете вызвать его.

1
добавлено

Если вы посмотрите в исходный код Guice, будет ясно, что на самом деле сделано:

final ThreadLocal localContext;

/** Looks up thread local context. Creates (and removes) a new context if necessary. */
 T callInContext(ContextualCallable callable) throws ErrorsException {
    Object[] reference = localContext.get();
    if (reference[0] == null) {
        reference[0] = new InternalContext();
        try {
            return callable.call((InternalContext)reference[0]);
        } finally {
           //Only clear the context if this call created it.
            reference[0] = null;
        }
    } else {
       //Someone else will clean up this context.
        return callable.call((InternalContext)reference[0]);
    }
}

По-видимому, когда ваш объект вводится, Guice хранит его в этой переменной ThreadLocal . Теперь, в соответствии с этим фрагментом кода, он будет немедленно освобожден по мере его ввода. Итак, возможно, в вашем «объеме» он инициализируется где-то еще, возможно, в начале инъекции - и в конце инъекции он отпущен.

0
добавлено
Я думаю, что это круговое обнаружение зависимостей. Я буду проверять его завтра и принять ваш ответ, потому что вы дали правильный намек.
добавлено автор Christian, источник
Да, проблема заключалась в бесконечном цикле. Спасибо
добавлено автор Christian, источник
Возможно, вы правы. Но я исправил это, позвонив get-Method провайдера позже, после инъекции.
добавлено автор Christian, источник
Вы уверены, что это бесконечное обнаружение цикла, а не признание того, что ресурс уже зарезервирован? Как и в, он уже построен? Эта ссылка reference [0] , вероятно, была установлена ​​в начале построения объекта и была выпущена в конце, поэтому при построении она всегда будет возвращать уже назначенную ссылку [0] , Это было бы моим предположением. Я могу ошибаться. По конструкции я, конечно, подразумеваю инъекцию.
добавлено автор Danyel, источник
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async