【发布时间】:2019-09-27 07:57:30
【问题描述】:
我有一个 REST 控制器
@Path("/greet")
@RequestScoped
public class GreetController {
@Inject
private GreeterService greeterService;
@GET
@Path("{name}")
@Produces(TEXT_PLAIN)
public String greet(@PathParam("name") String name) {
return greeterService.greet(name);
}
}
使用 GreeterService
@RequestScoped
public class GreeterService {
@Inject
private Greeter greeter;
public String greet(String name) {
return greeter.greet(name);
}
}
GreeterService 本身注入了一个具有两个实现的接口
@RequestScoped
@Hello
public class HelloGreeter implements Greeter {
@Override
public String greet(String name) {
return "Hello " + name;
}
}
和
@RequestScoped
@Whazzup
public class WhazzupGreeter implements Greeter {
@Override
public String greet(String name) {
return "Whazzup " + name;
}
}
@Whazzup 和 @Hello 只是限定符。
我正在尝试根据 GreetController 中使用的限定符将Greeter-Interface 的正确实现注入GreeterService。
这甚至可以使用 CDI 吗?
一个简单的解决方法当然是为每个限定符设置两个 GreeterServices,但这似乎不是一个好主意,因为当添加新的限定符时,GreeterServices 的数量会增加。
当然,这只是一个基本示例,不需要 GreeterServcie,但我不允许将我的公司代码发布到 StackOverflow,因此我必须实现一个简单的示例来重现我们的架构。
提前致谢!
【问题讨论】:
-
您的描述似乎与您所说的要实现的目标有些矛盾。通过在
GreeterController的注入点上放置一个限定符,您就是说您想要一个具有给定限定符的GreeterService的实现。例如。对于@Inject @Wazzup GreeterService service,必须有一个GreeterService类型和限定符@Wazzup的bean。因此,您使用的限定符越多,您需要的 bean 就越多。 -
您还可以有一个“终极生产者”,它为给定类型的所有注入点创建 bean,并基于检查注入点来实现。从那里,您可以看到使用了什么限定符。这就是你所追求的吗?不过,它仍然需要您在
@Inject Greeter greeter;上指定一个限定符。 -
我想要的是我的
GreeterService根据我在GreetController中提供的注释选择Greeter的正确实现。我不知道这是否是实现这种行为的正确方法。 -
GreeterService类级别的限定注释和控制器中的字段greeterService只是我尝试的一部分。我在原始帖子中删除了它们。也许这让我的意图更加明确:我想根据控制器控制Greeter的哪个实现将注入GreeterService。 -
我在注入时没有看到合格的注释。谁应该有责任决定应该注入什么 Greeter。那一个应该能够使用限定符。
标签: jakarta-ee dependency-injection cdi