You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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")注入

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:54:53