在Payara中是否需CDI<->HK2桥接器使@Stateless EJB被HK2注入?
解决Payara中@Stateless REST资源注入CDI EJB的HK2依赖问题
问题根源
Payara(基于GlassFish)的JAX-RS实现(Jersey)默认使用HK2作为依赖注入容器,而OpenLiberty统一通过WELD处理所有注入场景(包括JAX-RS)。当REST资源标注为@Stateless时,HK2不会自动感知CDI管理的EJB,导致注入失败——即便CDI已经正确发现了EJB(从日志的JNDI注册信息可验证)。
是否需要CDI-HK2桥接?
是,这是Payara/GlassFish环境下的标准解决方案,目的是让HK2能够复用CDI的Bean管理能力,解决跨容器的注入问题。
最佳实践方案
方案1:使用HK2-CDI桥接(推荐)
通过官方提供的HK2-CDI桥接组件,让HK2委托CDI处理所有注入请求,无需手动注册Bean。
步骤1:添加依赖(Maven示例)
确保依赖版本与Payara 6的HK2版本匹配(Payara 6对应HK2 3.x):
<dependency> <groupId>org.glassfish.hk2</groupId> <artifactId>hk2-cdi-bridge</artifactId> <version>3.0.3</version> <scope>provided</scope> </dependency>
步骤2:注册HK2CDIFeature到JAX-RS应用
在你的JAX-RS应用类中,注册HK2CDIFeature:
import jakarta.ws.rs.ApplicationPath; import org.glassfish.hk2.cdi.HK2CDIFeature; import org.glassfish.jersey.server.ResourceConfig; @ApplicationPath("/api") public class ApiApplication extends ResourceConfig { public ApiApplication() { // 注册桥接Feature register(HK2CDIFeature.class); // 注册你的REST资源类 register(ReleasesResource.class); } }
此配置会让HK2自动通过CDI的BeanManager查找依赖,包括所有CDI管理的EJB。
方案2:自定义HK2绑定器(按需注册)
如果不需要全局桥接,仅需注册特定EJB到HK2,可以自定义绑定器通过CDI的BeanManager获取Bean实例:
步骤1:实现HK2绑定器
import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import org.glassfish.hk2.utilities.binding.AbstractBinder; import com.example.application.control.AppResponseBuilder; public class CDIBridgeBinder extends AbstractBinder { @Inject private BeanManager beanManager; @Override protected void configure() { // 注册AppResponseBuilder到HK2 bindFactory(() -> { var bean = beanManager.resolve(beanManager.getBeans(AppResponseBuilder.class)); return beanManager.getReference(bean, AppResponseBuilder.class, beanManager.createCreationalContext(null)); }).to(AppResponseBuilder.class); } }
步骤2:注册绑定器到JAX-RS应用
import jakarta.ws.rs.ApplicationPath; import org.glassfish.jersey.server.ResourceConfig; @ApplicationPath("/api") public class ApiApplication extends ResourceConfig { public ApiApplication() { register(CDIBridgeBinder.class); register(ReleasesResource.class); } }
关于@Resource注入失败的说明
你推测的逻辑正确:HK2在初始化REST资源时会优先处理自身的注入流程,而@Resource的JNDI lookup是后续执行的,因此无法解决HK2的依赖缺失问题。必须让HK2能够直接找到目标Bean,才能解决注入异常。
是否需要自行发现所有CDI Bean?
不需要。方案1的HK2-CDI桥接会自动复用CDI的Bean发现机制,无需手动遍历或注册所有Bean。仅当你需要对注入做精细控制时,才需要采用方案2的手动注册方式。
内容的提问来源于stack exchange,提问作者mikee
相关产品推荐
相关产品推荐

