CDI注入报错:带@CustomQualifier的AbstractDao依赖无法解析
CDI依赖注入失败:WELD-001408 未满足依赖问题
报错信息
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type AbstractDao with qualifiers @CustomQualifier at injection point [BackedAnnotatedField] @Inject @CustomQualifier private com.example.MyBean.dao at com.example.MyBean.dao(MyBean.java:0)
相关代码片段
CustomQualifier.java
package com.example.annotations; import jakarta.inject.Qualifier; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Qualifier @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE}) public @interface CustomQualifier { String value(); }
AbstractDao.java
package com.example.dao; public abstract class AbstractDao { // Abstract methods and common functionality }
DaoImpl.java
package com.example.dao; import com.example.annotations.CustomQualifier; import jakarta.enterprise.context.ApplicationScoped; @CustomQualifier("daoImpl") @ApplicationScoped public class DaoImpl extends AbstractDao { // Implementation of abstract methods }
MyBean.java
package com.example; import com.example.annotations.CustomQualifier; import com.example.dao.AbstractDao; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; import jakarta.inject.Named; import java.io.Serializable; @Named @SessionScoped public class MyBean implements Serializable { @Inject @CustomQualifier("daoImpl") private AbstractDao dao; // Other methods and properties }
beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd" version="4.0" bean-discovery-mode="annotated"> </beans>
依赖项
<dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-shaded</artifactId> <version>5.1.3.Final</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>jakarta.faces</artifactId> <version>4.0.8</version> </dependency>
环境信息
- Java 17
- PrimeFaces 14
- Tomcat 10.1.x
- Spring 6
问题描述
CDI容器无法解析带有@CustomQualifier("daoImpl")限定符的AbstractDao依赖。已给DaoImpl类添加相同限定符和作用域注解,但MyBean中的注入点仍然失败。
已尝试操作
- 确认
DaoImpl类已标注@CustomQualifier("daoImpl")和@ApplicationScoped - 验证
MyBean中的注入点已正确标注@CustomQualifier("daoImpl")
问题原因与解决方案
1. 限定符匹配细节问题
带值的限定符需要严格匹配属性值:
- 检查拼写:确认注入点和实现类的
"daoImpl"完全一致(无大小写、空格错误) - 显式指定属性名:可以把注解写成
@CustomQualifier(value="daoImpl"),避免隐式属性识别的潜在问题
2. Bean发现模式与扫描范围
当前beans.xml设置bean-discovery-mode="annotated",仅扫描带CDI注解的类:
- 检查
DaoImpl是否被正确编译到WEB-INF/classes目录,Tomcat下Weld默认扫描该目录下的所有包,打包缺失会导致Bean不被发现 - 临时修改
bean-discovery-mode="all",强制扫描所有类,如果注入成功,说明原模式下Bean未被正确识别(可能是注解组合未被CDI判定为"annotated"类)
3. Spring与CDI容器冲突
Spring和Weld是两套独立的DI体系,共存时易出现冲突:
- 检查Spring是否开启了
@ComponentScan扫描com.example.dao包:如果Spring扫描到DaoImpl,会将其作为Spring Bean管理,CDI容器无法获取 - 解决方案:
- 若优先使用CDI:移除Spring对该包的组件扫描,确保Weld完全管理
DaoImpl - 若优先使用Spring:将
DaoImpl添加@Component注解,改用Spring的@Autowired+@Qualifier("daoImpl")注入
- 若优先使用CDI:移除Spring对该包的组件扫描,确保Weld完全管理
4. Tomcat中Weld的配置缺失
Tomcat是Servlet容器,需手动配置Weld才能启用CDI:
- 在
WEB-INF/web.xml中添加Weld监听器:
<listener> <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class> </listener>
- 确认
weld-servlet-shaded依赖已正确打包到WEB-INF/lib目录,Tomcat能加载到该jar包
5. Bean构造方法问题
CDI要求Bean具备公共无参构造:
- 若
DaoImpl自定义了带参构造,需手动添加公共无参构造方法,否则CDI无法实例化Bean
内容的提问来源于stack exchange,提问作者sparker
相关产品推荐
相关产品推荐

