CDI-Bean名称不明确

时间:2018-10-03 22:40:05

标签: java cdi

我定义了两个Bean:

@Named("mysql")
public MySqlLogService extends AbstractLogService { ... }

@Named("mysql")
public MySqlConcurrencyService implements ConcurrencyService { ... }

我认为Named限定词在某种程度上与Bean的类型有关,但是Weld返回:

Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001414: Bean name is ambiguous. Name mysql resolves to beans: 
  - Managed Bean [class my.package.MySqlConcurrencyService] with qualifiers [@Default @Named @Any],
  - Managed Bean [class my.other.package.MySqlLogService] with qualifiers [@Default @Named @Any]

为什么?资格赛的范围是什么?

2 个答案:

答案 0 :(得分:2)

似乎您在混淆CDI注释。 @Named("my_custom_name")注释用于显式地引用该类/ impl,例如:

@Inject
@Named("my_custom_name")
ConcurrencyService service;

如果您没有在@Named内定义自定义名称,那么默认情况下它将选择类名称,因此您不会遇到该错误。 在您的示例中:

@Named
MySqlLogService

将被称为mySqlLogService

@Named
MySqlConcurrencyService

将被称为mySqlConcurrencyService,但我仍然不明白您要达到的目标。

未使用@Named定义范围,而是使用:

@RequestScoped
@SessionScoped
@ApplicationScoped
@ConversationScoped

更多信息here,这是两个示例i ii

对于范围,请检查oracle的page

也是一个不错的博客,解释了Qualifiers

答案 1 :(得分:0)

对于两个启用的bean,无论类型如何,都不能具有相同的bean名称(通过@Named)。

由于它是CDI,我们如何看待CDI规范? 让我们从2.6. Bean names开始,它指出:

  

...在非类型安全的环境(如统一表达式语言)中使用具有名称的bean时,可以使用其名称来引用。...

因此,您可以在不引用其类型的情况下使用该bean。因此,要求能够将bean名称解析为一个特定bean。用例是,例如,当您从JSF页面使用EL时。

再进一步,它显示为:

  

要遵守Ambiguous names中定义的限制,多个bean可能共享相同的bean名称。

这可以使您实际上“破坏”名称的唯一性,只要您可以保证在类型安全解析结束时,只会找到具有该给定名称的一个bean。

确保您的bean具有唯一的名称,并且可以使用。 如果仅是限定词,那么使用@Named可能会增加您可能不需要的开销。只需创建自己的限定词并从那里开始。