WELD-001308(空限定符)错误场景咨询|Java 8 Wildfly 10.1.0 Ubuntu 16.04
我在处理Wildfly 10.x的CDI问题时经常碰到这个错误,结合你的技术栈,下面是几个最容易触发该错误的实际场景,都是项目里踩过的坑:
注入点无明确限定符且存在多个同类型Bean
这是最常见的情况:当你用@Inject注入某个接口/父类类型,但该类型有多个实现类都被CDI管理(比如都加了@Default或没加任何限定符),容器无法确定要注入哪个实例,就会抛出WELD-001308。举个例子:// 两个同接口的实现类,均被CDI管理 public class PaymentServiceImpl implements PaymentService {} public class MockPaymentServiceImpl implements PaymentService {} // 注入点未指定限定符,容器无法抉择 @Inject private PaymentService paymentService; // 此处会触发错误Wildfly 10搭载的WELD 2.3.x对这种歧义检查非常严格,哪怕是默认限定符的重复也会触发错误。
自定义限定符注解定义不规范
如果你自己编写了限定符,但忘记添加@Qualifier元注解,或者元注解的目标范围配置不全,CDI会不识别这个注解为合法限定符。比如错误的定义:// 缺少@Qualifier元注解,CDI不认为这是有效限定符 @Target({TYPE, FIELD}) @Retention(RUNTIME) public @interface Mock {}当你用这个注解标注Bean或注入点时,容器会把它当作空限定符处理,进而触发错误。正确的限定符必须包含
@Qualifier:@Qualifier @Target({TYPE, METHOD, PARAMETER, FIELD}) @Retention(RUNTIME) public @interface Mock {}Bean的限定符配置冲突或缺失
比如某个Bean被错误地标注了多个互斥的限定符,或者原本需要带限定符的Bean遗漏了配置。举个例子:你把一个Bean同时标注为@Default和@Alternative,但注入点没有指定具体限定符,容器无法筛选出正确的Bean;或者你启用了多个同类型的@AlternativeBean,但注入点没做限定。第三方依赖库中的Bean引发歧义
如果你引入的第三方Java EE库中包含多个同类型的CDI Bean,而你的代码直接注入该类型却没有指定限定符,就会触发错误。比如某些JAX-RS客户端库、持久化库可能提供了多个实现类,直接@Inject ClientBuilder就会因为候选Bean过多而报错。Wildfly部署配置或模块冲突
Wildfly 10的模块机制可能导致冲突:如果你的应用部署包(WAR/EAR)和Wildfly自带模块中存在同类型的CDI Bean,且都没有明确限定符,容器会无法分辨。另外,beans.xml的配置错误也会引发问题,比如在<alternatives>中同时启用多个同类型Bean,或者<interceptors>配置导致限定符解析异常。测试环境中的注入问题
如果你用Arquillian做集成测试,测试类中的注入点没有正确配置限定符,或者测试部署的Bean集合有重复(比如测试类和主代码中有同类型Bean),也会触发这个错误。另外,自定义CDI扩展(实现Extension接口)在处理Bean元数据时出错,也可能导致限定符为空的情况。
内容的提问来源于stack exchange,提问作者fareed

