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

在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:49:59