从注入的实例 CDI 中获取确切的对象
Get exact object from injected instance CDI
我有一些 DAO,如 UserDAO, ProductDAO
等,没有 cdi 注释或限定符(那么它们是 @Default
)。这些 classes 实现了抽象 DAO:
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();
但抛出异常:
Exception in thread "main"
javax.enterprise.inject.AmbiguousResolutionException: Too many beans
match, because they all have equal precedence.
所以 问题 是我不能使用很多限定符,因为我有很多实体,以后可以添加它们。我需要一种通用方法,可以找到并提取具有请求类型的对象,如上例所示。而且它不应该使用 class 名称或任何字符串名称来表示所需的类型或 class。例如。 public DAO getNeededDAO(String neededClassName)
。它必须动态检测所需的 type/class。可以吗?
更新
我正需要这个:
UserDAO user = chooseAndGetRequiredDAO();
所以chooseAndGetRequiredDAO()
必须明白UserDAO类型是必需的。它必须寻找存在的 DAO,如果找到就选择 UserDAO。也许它应该使用反射器或任何 DAO 工厂,我不确定。
要么你:
- 使用
@Named
- 注入实际接口,例如
UserDAO
、OrderDAO
、...(正确的方式)
- 使用您在运行时调用的方法
T build(Class<T>)
注入 DAOFactory
factory.build(User.class).getById(id)
(我 不 建议这样做)
你或许可以专门化你的 DAO,如果可以的话,可以使用通用参数:
public interface DAO<T> {
...
}
然后您可以使用通用参数区分不同的参数。虽然这只适用于 CDI bean,但不适用于 EJB(我认为)
@Inject
private DAO<User> userDao;
如果你真的想要所有个DAO,你必须迭代allDAOs
。在你的例子中:
for(DAO dao: allDAOs) {
...do something with dao...
}
您的 allDAOs
字段允许您对类型集中具有 DAO
类型的所有 bean 执行 programmatic lookup。
但是要进行查找,您必须提出搜索请求。在那种特殊情况下,类型和限定符的组合。
UserDAO user = allDAOs.select(UserDao.class).get();
我有一些 DAO,如 UserDAO, ProductDAO
等,没有 cdi 注释或限定符(那么它们是 @Default
)。这些 classes 实现了抽象 DAO:
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();
但抛出异常:
Exception in thread "main" javax.enterprise.inject.AmbiguousResolutionException: Too many beans match, because they all have equal precedence.
所以 问题 是我不能使用很多限定符,因为我有很多实体,以后可以添加它们。我需要一种通用方法,可以找到并提取具有请求类型的对象,如上例所示。而且它不应该使用 class 名称或任何字符串名称来表示所需的类型或 class。例如。 public DAO getNeededDAO(String neededClassName)
。它必须动态检测所需的 type/class。可以吗?
更新
我正需要这个:
UserDAO user = chooseAndGetRequiredDAO();
所以chooseAndGetRequiredDAO()
必须明白UserDAO类型是必需的。它必须寻找存在的 DAO,如果找到就选择 UserDAO。也许它应该使用反射器或任何 DAO 工厂,我不确定。
要么你:
- 使用
@Named
- 注入实际接口,例如
UserDAO
、OrderDAO
、...(正确的方式) - 使用您在运行时调用的方法
T build(Class<T>)
注入DAOFactory
factory.build(User.class).getById(id)
(我 不 建议这样做)
你或许可以专门化你的 DAO,如果可以的话,可以使用通用参数:
public interface DAO<T> {
...
}
然后您可以使用通用参数区分不同的参数。虽然这只适用于 CDI bean,但不适用于 EJB(我认为)
@Inject
private DAO<User> userDao;
如果你真的想要所有个DAO,你必须迭代allDAOs
。在你的例子中:
for(DAO dao: allDAOs) {
...do something with dao...
}
您的 allDAOs
字段允许您对类型集中具有 DAO
类型的所有 bean 执行 programmatic lookup。
但是要进行查找,您必须提出搜索请求。在那种特殊情况下,类型和限定符的组合。
UserDAO user = allDAOs.select(UserDao.class).get();