Tomcat 10.1.17中RESTEasy应用与资源的CDI注入失效问题
问题
在Tomcat 10.1.17的RESTEasy资源中启用CDI时遇到注入失效问题:
- 部署环境:JKube 1.16.2 + Tomcat 10.1.17容器
- 技术栈:RESTEasy 6.2.8.Final(REST服务)、Weld 5.1.2(CDI实现)
- 现有配置:
- WEB-INF下存在空的
beans.xml文件 - META-INF/context.xml配置:
<Context> <Resource name="BeanManager" auth="Container" type="jakarta.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory"/> </Context> - web.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app 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/web-app_5_0.xsd" metadata-complete="false" version="5.0"> <!-- Default page to serve --> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app> - pom.xml核心依赖:
<!-- RESTEasy stuff --> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-cdi</artifactId> <version>6.2.8.Final</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-client</artifactId> <version>6.2.8.Final</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson2-provider</artifactId> <version>6.2.8.Final</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-servlet-initializer</artifactId> <version>6.2.8.Final</version> </dependency> <dependency> <groupId>jakarta.enterprise</groupId> <artifactId>jakarta.enterprise.cdi-api</artifactId> <version>4.0.1</version> </dependency> <!-- CDI Implementation: --> <dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-shaded</artifactId> <version>5.1.2.Final</version> </dependency>
- WEB-INF下存在空的
- 现象:日志显示Weld初始化正常,Servlet/Filter/Listener中的
@Inject生效,但标注@Path的资源类和@ApplicationPath的Application类中@Inject完全失效。
解决方案
1. 显式注册RESTEasy CDI初始化监听器
在web.xml中添加RESTEasy的CDI集成监听器,确保RESTEasy资源被纳入CDI容器管理:
<listener> <listener-class>org.jboss.resteasy.cdi.ResteasyCdiInitializer</listener-class> </listener>
这个监听器负责打通RESTEasy和CDI的集成链路,让CDI能够处理JAX-RS资源类的依赖注入。
2. 确保资源类符合CDI Bean规范
给@Path资源类和@ApplicationPath类添加CDI作用域注解(如@RequestScoped),显式声明它们为CDI托管Bean:
@Path("/demo") @RequestScoped public class DemoResource { @Inject private DemoService demoService; // ... }
注意:类必须是非抽象、非内部类,且包含无参构造函数(或由CDI管理的构造函数)。
3. 调整CDI Bean发现模式
空beans.xml在CDI 4.0中默认使用bean-discovery-mode="annotated",仅识别带CDI注解的类。修改WEB-INF/beans.xml,设置发现模式为all,让CDI扫描所有类:
<?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="all"> </beans>
4. 显式配置RESTEasy Servlet(可选)
若自动初始化顺序存在问题,可在web.xml中显式配置RESTEasy Servlet,确保其在CDI初始化后加载:
<servlet> <servlet-name>ResteasyServlet</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> <init-param> <param-name>jakarta.ws.rs.Application</param-name> <param-value>your.package.YourJaxrsApplication</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ResteasyServlet</servlet-name> <url-pattern>/api/*</url-pattern> </servlet-mapping>
5. 排查依赖冲突
执行mvn dependency:tree检查依赖树,确保resteasy-cdi的所有子依赖未被排除,且RESTEasy与CDI版本兼容(RESTEasy 6.x对应CDI 4.x,你的版本匹配)。
内容的提问来源于stack exchange,提问作者Oberon
相关产品推荐
相关产品推荐

