Получить точный объект из введенного экземпляра CDI
У меня есть некоторые DAO, такие как UserDAO, ProductDAO
и т. д. без аннотаций cdi или квалификаторов (тогда они @Default
). Эти классы реализуют абстрактное Дао:
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();
Но это вызывает исключение:
Исключение в потоке " main" класса javax.предприятие.впрыскивать.AmbiguousResolutionException: слишком много бобов совпадают, потому что все они имеют одинаковый приоритет.
Таким образом, проблемасостоит в том, что я не могу использовать много квалификаторов, потому что у меня есть много сущностей, и они могут быть добавлены позже. Мне нужен один универсальный метод, который может найти и извлечь объект с запрошенным типом, как это было показано в примере выше. И он не должен использовать имя класса или любые строковые имена, чтобы не указывать нужный тип или класс. Например, public DAO getNeededDAO(String neededClassName)
. Оно имеет динамическое определение требуемого типа / класса. Можно ли это сделать?
Обновить
Мне нужно именно это:
UserDAO user = chooseAndGetRequiredDAO();
Поэтому chooseAndGetRequiredDAO()
должен понимать, что требуется тип UserDAO. Он должен искать существующие DAOs и выбирать UserDAO, если найдет. Может быть, он должен использовать reflecton или любую другую фабрику DAO, я не уверен.
3 ответа:
Ваше поле
allDAOs
позволяет выполнятьпрограммный поиск для всех бобов, имеющих типDAO
в их наборе типов. Но чтобы сделать поиск, вы должны дать запрос на поиск. В данном конкретном случае это комбинация типа и квалификаторов.UserDAO user = allDAOs.select(UserDao.class).get();
Либо вы:
- использовать
@Named
- ввести фактический интерфейс, например
UserDAO
,OrderDAO
, ... (правильный путь)- введите
DAOFactory
с помощью методаT build(Class<T>)
, который вы вызываете во время выполнения, как этоfactory.build(User.class).getById(id)
(я не предлагаю это)
Возможно, вы могли бы специализировать DAOs, если это возможно с помощью универсального параметра:
public interface DAO<T> { ... }
После этого вы можете различать различные варианты с помощью универсального параметра. Хотя это работает только для CDI beans, а не для EJBs (я думаю)
@Inject private DAO<User> userDao;
Если вы действительно хотите все DAOs, вы должны повторить
allDAOs
. В вашем примере:for(DAO dao: allDAOs) { ...do something with dao... }