从注入的实例 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
  • 注入实际接口,例如UserDAOOrderDAO、...(正确的方式)
  • 使用您在运行时调用的方法 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();