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

Jersey 2中如何为可注入类设置值以在API资源注入时可用?

解决Jersey 2.x中注入后调用对象方法的问题

背景

已从Jersey 1.19迁移至Jersey 2.41(搭配HK2与Jetty 10.0.20),使用Java 17。此前成功搭建v1版本REST服务器,现需完成v2版本适配。在v1代码中,可在启动HTTPServer的类中为待注入类ISyslogServerParms设置值,但在Jersey 2中尝试多次均未成功。目前ISyslogServerParms的注入已正常完成,但找不到合适位置调用setEventTrackers()方法。

原Jersey 1.x实现代码

Injector injector = Guice.createInjector(new SyslogAPIModule());
ISyslogServerParms serverParms = injector.getInstance(ISyslogServerParms.class);
serverParms.setEventTrackers(eventTrackers);

当前Jersey 2.x代码结构

API类

package com.w3p.api;
@Path("njams")
public class MyMessageAPI { 
    @Inject
    private ISyslogServerParms syslogServerParms;

    @POST
    @Path("syslog")
    @Consumes(MediaType.TEXT_XML)
    public Response handleSysLogMsg(String syslogData) {
        // 业务逻辑
    }
}

REST服务器类

public class MyRestServer {

    private final List<String> eventTrackers; 
    
    public MyRestServer(List<String> eventTrackers) {            
        this.eventTrackers = eventTrackers;
    }

    public void run() {
        ApplicationConfig config = new ApplicationConfig(eventTrackers);
        // 启动Jetty服务器的逻辑
    }
}

ResourceConfig类

public class ApplicationConfig extends ResourceConfig{  
    @Inject
    public ApplicationConfig(List<String> eventTrackers) {
       packages("com.w3p.api");       
       register(new ApplicationBinder());
       ServiceLocator locator = ServiceLocatorFactory.getInstance().create("MyMessageAPI");
       ISyslogServerParms parms = locator.getService(ISyslogServerParms.class); 
       parms.setEventTrackers(eventTrackers);
    }
}

问题原因

你手动创建的ServiceLocator和Jersey内部实际使用的不是同一个实例,因此无法获取到已注册的ISyslogServerParms对象,导致parms为null。

解决方案

方法1:绑定阶段直接初始化实例(推荐)

在HK2的Binder中创建ISyslogServerParms实例并设置eventTrackers,绑定后注入时直接使用已初始化完成的对象。

  1. 修改ApplicationConfig,将eventTrackers传入Binder:
public class ApplicationConfig extends ResourceConfig{  
    public ApplicationConfig(List<String> eventTrackers) {
       packages("com.w3p.api");       
       register(new ApplicationBinder(eventTrackers));
    }
}
  1. 修改ApplicationBinder,在绑定逻辑中初始化实例:
public class ApplicationBinder extends AbstractBinder {
    private final List<String> eventTrackers;

    public ApplicationBinder(List<String> eventTrackers) {
        this.eventTrackers = eventTrackers;
    }

    @Override
    protected void configure() {
        // 替换为你的ISyslogServerParms实现类
        SyslogServerParms serverParms = new SyslogServerParms();
        serverParms.setEventTrackers(eventTrackers);
        bind(serverParms).to(ISyslogServerParms.class);
    }
}

这种方式符合依赖注入的设计原则,避免了后续手动修改注入对象的状态。

方法2:获取Jersey实际使用的ServiceLocator

通过@Inject获取Jersey内部的ServiceLocator,直接从中获取ISyslogServerParms实例并调用方法:

public class ApplicationConfig extends ResourceConfig{  
    @Inject
    public ApplicationConfig(List<String> eventTrackers, ServiceLocator serviceLocator) {
       packages("com.w3p.api");       
       register(new ApplicationBinder());
       
       ISyslogServerParms parms = serviceLocator.getService(ISyslogServerParms.class); 
       if (parms != null) {
           parms.setEventTrackers(eventTrackers);
       }
    }
}

注意:这种方式需要确保ISyslogServerParms已经在Binder中完成绑定,否则可能仍会获取到null。如果使用延迟绑定,可调用serviceLocator.getServiceHandle(ISyslogServerParms.class).getService()强制初始化实例。

内容的提问来源于stack exchange,提问作者John Ormerod

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 17:17:46