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

Jersey中替代Spring @Bean及@PreDestroy的方案咨询

Jersey中创建线程池Bean及应用关闭时销毁的方案

一、创建Executor线程池Bean的替代方案

Jersey依赖HK2作为默认的DI容器,替代Spring中@Bean的方式是通过HK2 Binder绑定线程池实例,具体有两种常见实现:

1. 直接绑定线程池实例

创建自定义AbstractBinder子类,在configure方法中初始化线程池并绑定为单例:

public class ExecutorBinder extends AbstractBinder {
    @Override
    protected void configure() {
        // 初始化自定义线程池(可根据业务调整参数)
        ExecutorService threadPool = new ThreadPoolExecutor(
            5, 10,
            60L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy()
        );
        // 绑定为单例,指定注入类型(Executor或ExecutorService)
        bind(threadPool).to(ExecutorService.class).in(Singleton.class);
    }
}

然后在Jersey应用配置类(继承ResourceConfig或带有@ApplicationPath的类)中注册该Binder:

@ApplicationPath("/api")
public class JerseyApplication extends ResourceConfig {
    public JerseyApplication() {
        // 注册自定义Binder
        register(new ExecutorBinder());
        // 扫描并注册资源类
        packages("com.yourpackage.resources");
    }
}

2. 使用Factory工厂类创建(灵活配置)

如果需要更灵活的初始化逻辑,可实现HK2的Factory接口,通过工厂类管理线程池的创建:

public class ExecutorServiceFactory implements Factory<ExecutorService> {
    @Override
    public ExecutorService provide() {
        // 按需初始化线程池
        return Executors.newCachedThreadPool();
    }

    @Override
    public void dispose(ExecutorService executorService) {
        // 可在此提前定义基础销毁逻辑
        executorService.shutdown();
    }
}

在Binder中绑定Factory:

public class ExecutorBinder extends AbstractBinder {
    @Override
    protected void configure() {
        bindFactory(ExecutorServiceFactory.class)
            .to(ExecutorService.class)
            .in(Singleton.class);
    }
}

后续在资源类或其他组件中通过@Inject注入ExecutorService即可使用。

二、应用关闭时销毁线程池的替代方案

对应Spring的@PreDestroy,Jersey有以下几种实现方式:

1. 通过Factory的dispose方法

在ExecutorServiceFactory的dispose方法中完善线程池销毁逻辑,HK2容器销毁单例实例时会自动调用该方法:

@Override
public void dispose(ExecutorService executorService) {
    executorService.shutdown();
    // 等待线程池终止,超时则强制关闭
    try {
        if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
            executorService.shutdownNow();
        }
    } catch (InterruptedException e) {
        executorService.shutdownNow();
        Thread.currentThread().interrupt();
    }
}

2. 使用HK2的@PreDestroy注解

创建单例管理类,注入线程池后用HK2的javax.inject.PreDestroy标记销毁方法:

@Singleton
public class ExecutorLifecycleManager {
    private final ExecutorService executorService;

    @Inject
    public ExecutorLifecycleManager(ExecutorService executorService) {
        this.executorService = executorService;
    }

    @PreDestroy
    public void shutdownThreadPool() {
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}

在Binder中注册该管理类:

bind(ExecutorLifecycleManager.class).to(ExecutorLifecycleManager.class).in(Singleton.class);

Jersey应用关闭时,HK2会自动调用带有@PreDestroy的方法。

3. 监听Jersey应用关闭事件

实现ApplicationEventListener,监听ApplicationEvent.Type.STOPPING事件(应用关闭前触发):

public class AppShutdownListener implements ApplicationEventListener {
    @Inject
    private ExecutorService executorService;

    @Override
    public void onEvent(ApplicationEvent event) {
        if (event.getType() == ApplicationEvent.Type.STOPPING) {
            // 执行线程池销毁逻辑
            executorService.shutdown();
            try {
                if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                executorService.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }

    @Override
    public RequestEventListener onRequest(RequestEvent requestEvent) {
        return null; // 无需处理请求事件时返回null
    }
}

在Jersey应用配置类中注册该监听器:

register(AppShutdownListener.class);

内容的提问来源于stack exchange,提问作者Rohit Raj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:05:33