Jakarta EE 9.1中JAX-RS资源CDI依赖注入失效问题
解决JAX-RS中CDI依赖注入失效的问题
针对你遇到的手动实例化类正常,但CDI注入提示实例不存在的问题,按以下步骤排查:
1. 确保beans.xml文件存在且配置正确
Jakarta EE 9+部分容器支持无beans.xml的隐式CDI扫描,但并非所有场景都兼容。在src/main/resources/META-INF/下创建beans.xml,配置如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://jakarta.ee/xml/ns/jakartaee" version="3.0" bean-discovery-mode="all"> </beans>
bean-discovery-mode="all"会强制容器扫描所有带CDI注解的类,避免遗漏。
2. 显式配置JAX-RS应用类
创建自定义的Application子类,确保容器能正确扫描到JAX-RS资源和CDI bean:
import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.core.Application; @ApplicationPath("/api") public class RestApplication extends Application { // 无需额外代码,容器会自动扫描当前包及子包的相关类 }
如果没有这个类,部分容器可能仅扫描JAX-RS资源,不会处理CDI bean的注入逻辑。
3. 修正JAX-RS资源类的CDI注解
你的LoginResource作为JAX-RS资源,需要被CDI容器管理才能注入其他bean,给它添加@RequestScoped(或其他合适的作用域注解):
@Path("/login") @RequestScoped public class LoginResource { @Inject private UserDAO userDAO; // ... 原有代码 }
默认情况下,JAX-RS资源可能不属于CDI bean,显式标注作用域后才能启用注入功能。
4. 检查CDI相关依赖的完整性
确保Maven依赖中包含Jakarta CDI的必要jar包:
- 如果你使用完整的Jakarta EE容器(如WildFly、Payara),只需添加API依赖(容器自带实现):
<dependency> <groupId>jakarta.enterprise</groupId> <artifactId>jakarta.enterprise.cdi-api</artifactId> <version>3.0.0</version> <scope>provided</scope> </dependency>
- 如果你使用Servlet容器(如Tomcat),需要额外添加CDI实现(如Weld):
<dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-core</artifactId> <version>4.0.3.Final</version> <scope>runtime</scope> </dependency>
5. 验证所有注入目标类的注解正确性
- 确认
UserDAO、DatabaseConnection的@ApplicationScoped注解导入的是Jakarta包:import jakarta.enterprise.context.ApplicationScoped;,不要使用旧的javax包注解(Jakarta EE 9已完全迁移到jakarta前缀)。 - 检查
UserDAO中注入的DatabaseProperties类是否添加了CDI作用域注解(如@ApplicationScoped),如果这个类未被CDI管理,会导致UserDAO注入失败,进而引发LoginResource的注入异常。
6. 清理项目并重启容器
- 执行
mvn clean install清理构建缓存,确保依赖和编译类都是最新的。 - 在IntelliJ中重新部署项目,重启应用服务器,避免容器缓存导致的注入失效。
内容的提问来源于stack exchange,提问作者Thefizzlee
相关产品推荐
相关产品推荐

