2016-01-04 4 views
1

У меня есть ресурс Джерси с введенным объектом фасада. Это настроено в моем ResourceConfig, и фасад впрыскивается хорошо. Фасад содержит класс DAO, который также должен быть введен и сконфигурирован в том же ResourceConfig. Теперь к моей проблеме; класс DAO имеет значение NULL. Таким образом, не вводили.Inject не работает для вложенных объектов [Jersey 2.22.1]

@ApplicationPath("/service") 
public class SystemSetup extends ResourceConfig { 

public SystemSetup() { 
    packages(false, "com.foo.bar"); 
    packages("org.glassfish.jersey.jackson"); 
    register(JacksonFeature.class); 

    final LockManager manager = getLockManager(); 
    final SessionFactory sessionFactory = getSessionFactory(); 
    register(new AbstractBinder() { 
     @Override 
     protected void configure() { 
      bindFactory(InjectFactory.getDaoFactory(sessionFactory)).to(Dao.class).in(Singleton.class); 
      bindFactory(InjectFactory.getFacadeFactory(manager)).to(Facade.class).in(Singleton.class); 
     } 
    }); 
} 

@Path("/") 
@Produces("text/json") 
public class ViewResource { 

    @Inject 
    private Facade logic; 

public class Facade { 

    @Inject 
    private Dao dao; //Not injected 

на заводе экземпляры довольно просты. Они просто вызывают конструктор и передают ему аргумент.

Странная вещь, что это сработало безусловным штрафом, когда я использовал bind (объект класса), а не bindFactory.

EDIT

Фабрики

class InjectFactory { 

    static Factory<Dao> getDaoFactory() { 
     return new Factory<Dao>() { 
      @Override 
      public Dao provide() { 
       return new Dao(new Object()); 
      } 

      @Override 
      public void dispose(Dao dao) {} 
     }; 
    } 

    static Factory<Facade> getFacadeFactory() { 
     return new Factory<Facade>() { 

      @Override 
      public Facade provide() { 
       return new Facade(); 
      } 

      @Override 
      public void dispose(Facade facade) {} 
     }; 
    } 
} 
+1

Вы можете разместить весь код, необходимый для воспроизведения проблемы? –

+0

Привет! Я создал очень простой и маленький проект, который воспроизводит эту проблему. Загрузите его на speedy.sh/qbsnJ/Dummy-Project.zip и запустите его с помощью «mvn clean install tomcat7: run-war» и перейдите на localhost: 9090/dummy/service/test в браузере. –

+0

В принципе, все, что вам нужно воспроизвести, - это объект с инъекционным полем (A). Объект A должен содержать другое поле ввода (B). Оба A и B регистрируются как bindFactory (заводской экземпляр). –

ответ

0

Как и в случае с большинством рамок Ди, когда вы начинаете инстанцировании вещи самостоятельно, это часто случается, что вы пиная рамки из уравнения. Это справедливо для экземпляров Factory, а также объектов, которые создает завод. Таким образом, экземпляр Facade никогда не затрагивает структуру, за исключением того, чтобы вводить его в класс ресурсов.

Вы можете удержать ServiceLocator и непосредственно вводить объекты самостоятельно, если хотите их создать самостоятельно. Вот пара вариантов.

1) Внесите ServiceLocator в экземпляр Factory, затем введите экземпляр Facade.

static Factory<Facade> getFacadeFactory() { 
    return new Factory<Facade>() { 

     @Context 
     ServiceLocator locator; 

     @Override 
     public Facade provide() { 
      Facade facade = new Facade(); 
      locator.inject(facade); 
      return facade; 
     } 

     @Override 
     public void dispose(Facade facade) {} 
    }; 
} 

@Inject 
public SystemSetup(ServiceLocator locator) { 
    packages("foo.bar.rest"); 
    packages("org.glassfish.jersey.jackson"); 
    register(JacksonFeature.class); 

    register(new AbstractBinder() { 
     @Override 
     protected void configure() { 
      bindFactory(InjectFactory.getDaoFactory()).to(Dao.class); 

      Factory<Facade> factory = InjectFactory.getFacadeFactory(); 
      locator.inject(factory); 
      bindFactory(factory).to(Facade.class); 
     } 
    }); 
} 

2) Или связать Factoryкласса, и пусть рамки впрыскивать ServiceLocator

public static class FacadeFactory implements Factory<Facade> { 

    @Context 
    ServiceLocator locator; 

    @Override 
    public Facade provide() { 
     Facade facade = new Facade(); 
     locator.inject(facade); 
     return facade; 
    } 

    @Override 
    public void dispose(Facade facade) {} 
} 

register(new AbstractBinder() { 
    @Override 
    protected void configure() { 
     bindFactory(InjectFactory.getDaoFactory()).to(Dao.class); 
     bindFactory(InjectFactory.FacadeFactory.class).to(Facade.class); 
    } 
}); 
+0

Спасибо за помощь. Это имеет большой смысл, когда вы объясняете это. Я буду больше читать о ServiceLocator. Получил это, чтобы работать кстати, следуя первому шагу, с небольшими изменениями. Я удалил аннотацию Inject в конструкторе SystemSetup (так как он не работал) и вместо этого добавил параметр @Context. –

+0

Если вы когда-либо работали с Spring, «ServiceLocator» аналогичен «ApplicationContext» Spring. Это основной контейнер IoC. –

 Смежные вопросы

  • Нет связанных вопросов^_^