Jersey-Guice не обрабатывает связанные ресурсы, если инжектор - ребенок? - PullRequest
3 голосов
/ 10 декабря 2011

Я использую Jersey-Guice для настройки приложения на Джерси, следуя этому шаблону .Все работает нормально, если Guice.createInjector() создает Injector, возвращенный методом GuiceServletContextListener.getInjector().Если этот инжектор является потомком другого инжектора, то связанные ресурсы (например, MyResource в приведенном ниже коде) никогда не добавляются в Jersey ResourceConfig, и Jersey аварийно завершает работу с жалобой на отсутствие корневых ресурсов.Я не думаю, что связанные ресурсы даже сканируются, потому что обычное «INFO: Регистрация my.example.MyResource в качестве корневого класса ресурсов» не появляется в журнале.

Любые идеи, почему это может бытьпроисходит?Обе версии показаны ниже.

В качестве дополнительного вопроса: я пытаюсь использовать дочерний инжектор, потому что хочу настроить объект службы данных приложения в моем классе Main ().Больше чем просто ресурсы Джерси нуждаются в доступе к нему.Мне все еще нужно, чтобы это впрыснули в ресурсы Джерси.

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

Эта версия работает.

public class MyConfig extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new ServletModule() {
            @Override
            protected void configureServlets() {
                bind(MyResource.class);
                serve("*").with(GuiceContainer.class);
            }
        });
    }
}

Однако следующий код не работает.

 public class MyConfig extends GuiceServletContextListener {
     final Injector parentInjector;

     public MyConfig(Injector injector) {
         this.parentInjector = injector;
     }

     @Override
     protected Injector getInjector() {
         return parentInjector.getChildInjector(new ServletModule() {
             @Override
             protected void configureServlets() {
                 bind(MyResource.class);
                 serve("*").with(GuiceContainer.class);
             }
         });
     }
 }

1 Ответ

5 голосов
/ 11 декабря 2011

Я понял это после некоторой забавы с отладчиком.

Ресурсы обнаруживаются путем итерации по привязкам инжектора, проверяя те, которые являются ресурсами или поставщиками.Используемый инжектор вводится в GuiceContainer через конструктор, подобный этому: public GuiceContainer(@Inject injector).Без явного связывания для GuiceContainer.class, указанного в дочернем инжекторе, родительский (то есть корневой) инжектор используется для создания экземпляра (точнее, связывание точно в срок), и, следовательно, родительский (а не дочерний) инжекторвнедрен в экземпляр GuiceContainer.

Исправление простое:

Явное связывание GuiceContainer.class в дочернем инжекторе.Следующий код работает

 public class MyConfig extends GuiceServletContextListener {
     final Injector parentInjector;

     public MyConfig(Injector injector) {
         this.parentInjector = injector;
     }

     @Override
     protected Injector getInjector() {
         return parentInjector.getChildInjector(new ServletModule() {
             @Override
             protected void configureServlets() {
                 /* Explicitly bind GuiceContainer so that
                  * the child, not root, injector is injected 
                  * into its constructor. */
                 bind(GuiceContainer.class);
                 bind(MyResource.class);
                 serve("*").with(GuiceContainer.class);
             }
         });
     }
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...