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
相关产品推荐
相关产品推荐

