定制/扩展Spring对shiro的@Async支持

2024-04-23

我正在使用Spring的@EnableAsync异步执行方法的功能。为了安全起见,我使用 Apache Shiro。在异步执行的代码中,我需要访问附加到触发异步调用的线程的 Shiro 主题。

Shiro 支持通过将主题与主题相关联来在不同线程中使用现有主题Callable将在不同的线程上执行(请参阅here https://shiro.apache.org/subject.html#a-different-thread):

Subject.associateWith(Callable)

不幸的是我无法直接访问Callable因为这个东西是Spring封装的。我发现我需要延长 Spring 的AnnotationAsyncExecutionInterceptor将我的主题与创建的主题联系起来Callable(这是简单的部分)。

现在的问题是如何让 Spring 使用我的自定义AnnotationAsyncExecutionInterceptor而不是默认的。默认的创建于AsyncAnnotationAdvisor and AsyncAnnotationBeanPostProcessor。我当然也可以扩展这些类,但这只会转变为问题,因为我需要让 Spring 再次使用我的扩展类。

有什么办法可以实现我想要的吗?

我也可以添加一个新的自定义异步注释。但我认为这不会有太大帮助。


UPDATE:实际上我的发现AnnotationAsyncExecutionInterceptor需要定制是错误的。一次偶然的机会我偶然发现了org.apache.shiro.concurrent.SubjectAwareExecutorService它完全符合我的要求,让我觉得我可以简单地提供一个自定义执行器,而不是自定义拦截器。详情请参阅我的回答。


我设法实现了我想要的 - shiro subject 自动绑定和取消绑定到由 spring 的异步支持执行的任务 - 通过提供扩展版本ThreadPoolTaskExecutor:

public class SubjectAwareTaskExecutor extends ThreadPoolTaskExecutor {

  @Override
  public void execute(final Runnable aTask) {
    final Subject currentSubject = ThreadContext.getSubject();
    if (currentSubject != null) {
      super.execute(currentSubject.associateWith(aTask));
    } else {
      super.execute(aTask);
    }
  }

  ... // override the submit and submitListenable method accordingly
}

为了让 spring 使用这个执行器,我必须实现一个AsyncConfigurer返回我的自定义执行器:

@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {

  @Override
  public Executor getAsyncExecutor() {
    final SubjectAwareTaskExecutor executor = new SubjectAwareTaskExecutor();
    executor.setBeanName("async-executor");
    executor.setCorePoolSize(10);
    executor.setMaxPoolSize(10);
    executor.initialize();
    return executor;
  }

  @Override
  public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return new SimpleAsyncUncaughtExceptionHandler();
  }
}

通过此更改,父线程的主题将自动在带有注释的方法中可用@Async并且 - 可能更重要 - 执行异步方法后,主题将与线程解除连接。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

定制/扩展Spring对shiro的@Async支持 的相关文章

随机推荐