通过@Produces将@Named限定符添加到现有bean时,CDI模糊不清

问题描述:

我在依赖jar文件中有一个CDI bean实现:

I have a CDI bean implementation in a dependency jar file:

@ApplicationScoped
public class MyService {
  public String doSomething() {...}
}

在我的webapp中,我想通过EL Expression访问该服务,因此我必须给它一个 @Named 注释。但我无法在 MyService 实现中添加注释,因为我无权更改该代码。

In my webapp, I want to access that service via EL Expression, therefore I have to give it a @Named annotation. But I cannot add the annotation on the MyService implementation because I don't have the rights to change that code.

因此我尝试创建一个生产者,如

Therefore I tried creating a producer like

public class MyServiceProducer {
  @Inject MyService myService;

  @Produces @Named("myService")
  public MyService produceNamedInstance() {
    return myService;
  }
}

这导致


WELD-001409 - 带有限定符的MyService类型的模糊依赖性@Default
...
可能的依赖项:
- Managed Bean [ class ... MyService] with qualifiers [@Any @Default]
- Producer Method [myService] with qualifiers [@Default @Named @Any]声明为[...]

WELD-001409 - ambiguous dependency for type MyService with qualifiers @Default ... Possible dependencies: - Managed Bean [class ...MyService] with qualifiers [@Any @Default] - Producer Method [myService] with qualifiers [@Default @Named @Any] declared as [...]

如何在不触及原始源代码的情况下添加 @Named 注释?

How can I add a @Named annotation without touching the original source code?

错误是指 @Inject MyService 。您基本上通过 @Produces MyService 定义了第二个bean,可注射为 MyService ,但是你没有明确指出你要通过 @Inject 注入哪一个。所以CDI感到困惑并抛出这种模糊的依赖错误。

The error is referring to the @Inject MyService. You basically defined a second bean via @Produces MyService which is also injectable as MyService, but you didn't make clear which one exactly you meant to inject via @Inject. So CDI got confused and throws this ambiguous dependency error.

你应该只扩展现有的bean然后命名它,而不是为已经自动生成的bean创建另一个生成器。 。

Instead of creating another producer for an already auto-produced bean, you should just extend the existing bean and then name it.

@Named("myService")
public class MyNamedService extends MyService {
    //
}

注意应该是范围已经 @Inherited ,因此您无需重新定义它。

Noted should be that the scope is already @Inherited, so you don't need to re-define it.