从注入的实例CDI

时间:2016-02-22 14:20:27

标签: java dependency-injection cdi

我有一些类似UserDAO, ProductDAO等的DAO,没有cdi注释或限定符(然后它们是@Default)。这些类实现了抽象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();

但它抛出异常:

  

线程“main”中的异常   javax.enterprise.inject.AmbiguousResolutionException:太多的bean   匹配,因为它们都具有相同的优先权。

所以问题是我不能使用很多限定符,因为我有很多实体,可以在以后添加。我需要一个通用方法,可以找到并提取具有请求类型的对象,如何在上面的示例中显示它。并且它不应该使用类名或任何字符串名来来定义所需的类型或类。例如。 public DAO getNeededDAO(String neededClassName)。它必须动态检测所需的类型/类。有可能吗?

更新

我需要这个:

UserDAO user = chooseAndGetRequiredDAO();

因此chooseAndGetRequiredDAO()必须了解UserDAO类型是必需的。必须查找存在的DAO并在找到时选择UserDAO。也许它应该使用reflecton或任何DAO工厂,我不确定。

3 个答案:

答案 0 :(得分:2)

您的allDAOs字段允许您对其类型设置为DAO类型的所有Bean执行programmatic lookup。 但要进行查找,您必须提供搜索请求。在特定情况下,类型和限定符的组合。

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

答案 1 :(得分:0)

要么你:

  • 使用@Named
  • 注入实际界面,例如UserDAOOrderDAO,...(正确方式)
  • 使用您在运行时调用的方法DAOFactory注入T build(Class<T>) factory.build(User.class).getById(id)(我建议这样做)

答案 2 :(得分:0)

如果可以使用通用参数:

,您可以专门设计DAO
public interface DAO<T> {
   ...
}

然后,您可以使用泛型参数区分不同的。虽然这只适用于CDI bean,但不适用于EJB(我认为)

@Inject
private DAO<User> userDao;

如果你真的想要所有 DAO,你必须迭代allDAOs。在您的示例中:

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