2016-02-22 3 views
2

У меня есть некоторые DAO, например UserDAO, ProductDAO и т. Д. Без аннотаций или отборочных cdi (это @Default). Эти классы реализуют абстрактные DAO:Получить точный объект из инъецированного экземпляра CDI

public interface DAO { 
    void update(); 
    void delete(); 
    void getById(long id); 
} 

Так я получаю все имеющиеся реализации DAO:

public class ClassToInjectIn { 
    @Inject 
    private Instance<DAO> allDAOs; 
} 

Теперь allDAOs содержит следующее:

[UserDAO, {@Default(), @Any()}] 
[ProductDAO, {@Default(), @Any()}] 

Например, мне нужно, чтобы получить UserDAO от этот случай, но я не могу. Я хочу сделать это так, как это:

UserDAO user = allDAOs.get(); 

Но он бросает исключение:

Исключение в потоке «главный» javax.enterprise.inject.AmbiguousResolutionException: Слишком много бобов матч, потому что все они имеют равный приоритет.

Так проблема в том, что я не могу использовать много классификаторов, потому что у меня есть много лиц, и они могут быть добавлены позже. Мне нужен один универсальный метод, который может найти и извлечь объект с запрошенным типом, как это было показано в примере выше. И он не должен использовать имя класса или любые имена строк для деинсталляции нужного типа или класса. Например. public DAO getNeededDAO(String neededClassName). Он должен динамически обнаруживать требуемый тип/класс. Можно ли это сделать?

UPDATE

мне нужно именно это:

UserDAO user = chooseAndGetRequiredDAO(); 

Так chooseAndGetRequiredDAO() должен понимать, что требуется тип UserDAO. Он должен искать существующие DAO и выбирать UserDAO, если находит. Возможно, он должен использовать рефлеон или любую фабрику DAO, я не уверен.

ответ

2

Ваше allDAOs поле позволяет выполнять programmatic lookup на все бобы, имеющих DAO типа в их типах установлен. Но для поиска вам нужно предоставить запрос на поиск. В этом конкретном случае сочетание типа и квалификаторов.

UserDAO user = allDAOs.select(UserDao.class).get(); 
+0

Боже мой, все было так просто. Благодарю. – nllsdfx

0

Либо:

  • использование @Named
  • вводят фактический интерфейс, например UserDAO, OrderDAO, ... (правильный путь)
  • впрыснуть DAOFactory с помощью метода T build(Class<T>), который вы использовали при время работы как это factory.build(User.class).getById(id) (я делаю не)
+0

Прочтите мое обновление, пожалуйста. – nllsdfx

0

Вы могли бы, возможно, специализировать свои объекты DAO, если это возможно, с общим параметром:

public interface DAO<T> { 
    ... 
} 

Затем можно различать разные из них с общим параметром.Несмотря на то, что работает только для CDI бобов, а не для EJBs (я думаю)

@Inject 
private DAO<User> userDao; 

Если вы действительно хотите всех объектов DAO, вы должны итерируют allDAOs. В вашем примере:

for(DAO dao: allDAOs) { 
    ...do something with dao... 
} 
+0

Прочтите мое обновление, пожалуйста. И я не могу вводить DAO точного типа. – nllsdfx

+0

Почему бы не вводить UserDAO напрямую? В противном случае см. Другой пост с 'select()'. –

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