Dependency injection CDI注入特定接口实现

Dependency injection CDI注入特定接口实现,dependency-injection,cdi,Dependency Injection,Cdi,假设我有一个界面Config 以及实现此接口的两个类别: class Config1: Config { } class Config2: Config { } 我通过使用Jackson反序列化JSON创建了其中一个实现,并希望将其作为公共库中的CDI ApplicationScope bean提供: @Produces @ApplicationScope fun config: Config { return mapper.readValue(json, Config) } 现在我有

假设我有一个界面
Config
以及实现此接口的两个类别:

class Config1: Config {
}

class Config2: Config {
}
我通过使用Jackson反序列化JSON创建了其中一个实现,并希望将其作为公共库中的CDI ApplicationScope bean提供:

@Produces
@ApplicationScope
fun config: Config {
  return mapper.readValue(json, Config)
}
现在我有两个应用程序,
App1
依赖于
Config1
App2
依赖于
Config2
。我想实现一个特性,例如,注入启动App1 Config1,或者抛出异常,即没有满足构造函数要求的bean。不幸的是,这不起作用:

类App1(val-config:Config1){}


有什么办法可以实现吗?或者我必须编写一个服务来执行实例检查?

您可能需要重新考虑该方法。对于您所拥有的,您甚至不能执行
instanceof
检查,因为您将获得一个代理,而不是实际的bean实例(因为您的生产者是
@ApplicationScoped

在CDI中,bean由其类型和限定符定义。从您的描述中,我理解您无论如何都需要区分这两种配置,因此将其抽象为接口是行不通的。您可以有两个producer方法,每个方法用于一个配置,并且具有不同的限定符。每个方法的外观如下所示:

@Produces
@ApplicationScoped
@Config1Qualifier //some custom qualifier that you slap on it
fun config: Config {
  return someFunctionThatResolvesIt()
}
然后,它的注入点将如下所示(使用Java语法):

这种方法的好处是,只要生产者方法上有正常的作用域(例如
@ApplicationScoped
),那么如果它们试图返回
null
,就会自动将其视为错误-这看起来像是您试图实现的


从完全不同的角度来看,您可以采用当前的生产者方法,将
@ApplicationScoped
更改为
@Dependent
@Singleton
,它们都不使用代理,也不允许执行
instanceof
。但是请注意,具体地说,
@Dependent
的行为可能与您想要的有所不同(假设您使用的是应用程序范围来保持单一实例)。

这两个都是我的想法,您可能会使用更多的调整,但描述相当笼统,我不得不对此做出疯狂的假设。例如,不清楚您是否总是仅实例化其中一个配置(这似乎是制作人所做的),这意味着您的一个应用程序总是抛出错误?
@Inject
@Config1Qualifier
Config config;