2015-07-29 4 views
0

Я использую HK2 в качестве рамки для инъекций зависимостей. Я создаю экземпляр State Machine внутри приложения. Итак, A < -> B вполне возможно, потому что в зависимости от входа, можно перейти обратно в А из В.HK2 Injection With Circular Dependency

@Singleton 
class StateManager extends SomeInterface{ 

    @Inject 
    private B b; 

    @Inject 
    private A a; 
} 

@Singleton 
class A extends State{ 

    @Inject 
    private B b; 

    @Inject 
    private StateManager sm; 

} 

@Singleton 
class B extends State{ 

    @Inject 
    private A a; 

    @Inject 
    private StateManager sm; 
} 

Как я могу добиться чего-то вроде этого? Вышеприведенный пример просто для иллюстрации. У меня больше состояний, чем в этом. Я попытался понять, является ли это дубликат, но не смог найти тот, который имеет дело. Когда я пытаюсь получить ServiceLocator.getService(StateManager.class), чтобы получить этот график, я получаю исключение циклической зависимости. Что лучше делать такие вещи?

ответ

2

Вы должны быть в состоянии ввести javax.inject.Provider<B>. От Javadoc

Предоставляет экземпляры T. Обычно реализуется инжектором. Для любого типа T, который можно вводить, вы также можете ввести Provider<T>. По сравнению с инъекционным T непосредственно, путем инъекций Provider<T> позволяет:

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

Тогда просто позвоните get(), когда вам это нужно

B b = bProvider.get(); 
+0

Я предпочитаю, чтобы избежать поставщика в моей модели домена. Но, если этого нельзя избежать, пусть будет так. Однако даже после этого. Я добавил метод PostConstruct для получения фактических экземпляров, вызвав 'aProvider.get()'. Проблема в том, что я также добавил 'PostConstruct' в A, где я делаю' smProvider.get() ', и он снова переходит в круговую зависимость. Кажется, это единственный способ нарушить это, имея сеттеры, которых я до сих пор пытался избежать. – vijar

+1

При использовании Провайдера вы часто не можете получить доступ к PostConstruct, так как это приведет к тому, что цикл снова будет там. HK2 гарантирует, что перед тем, как что-либо будет вложено во что-либо другое (или просмотрено), что экземпляр полностью инициализирован *, который включает вызов PostConstruct (с исключениями для прокси). – jwells131313