自定义/扩展Spring对shiro的@Async支持 [英] Customize/Extend Spring's @Async support for shiro

查看:169
本文介绍了自定义/扩展Spring对shiro的@Async支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using Spring's @EnableAsync feature to execute methods asynchronously. For security I'm using Apache Shiro. In the code that is executed asynchronously I need to have access to the Shiro subject that was attached to the thread that triggered the async call.

Shiro通过将主题与要在不同线程上执行的 Callable 关联起来,支持在不同线程中使用现有主题(请参阅

Shiro supports using an existing subject in a different thread by associating the subject with the Callable that is to be executed on the different thread (see here):

Subject.associateWith(Callable)

不幸的是,我没有直接访问 Callable 的权限,因为这些东西是由Spring封装的.我发现我需要扩展Spring的 AnnotationAsyncExecutionInterceptor ,以将我的主题与创建的 Callable 关联起来(这很容易).

Unfortunately I don't have direct access to the Callable as this stuff is encapsulated by Spring. I found that I would need to extend Spring's AnnotationAsyncExecutionInterceptor to associate my subject with the created Callable (that's the easy part).

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

By problem is now how to make Spring use my custom AnnotationAsyncExecutionInterceptor instead of the default one. The default one is created in AsyncAnnotationAdvisor and AsyncAnnotationBeanPostProcessor. I can of course extend these classes as well, but this only shifts to problem as I need the make Spring use my extended classes again.

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

Is there any way to achieve what I want?

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

I would be fine with adding a new custom async annotation as well. But I don't think this would be much of a help.

更新:实际上,我发现需要自定义 AnnotationAsyncExecutionInterceptor 是错误的.偶然地,我偶然发现了 org.apache.shiro.concurrent.SubjectAwareExecutorService ,它完全符合我的要求,并让我认为我可以简单地提供一个自定义执行器,而不是自定义拦截器.有关详细信息,请参见我的答案.

UPDATE: Actually my finding that AnnotationAsyncExecutionInterceptor would need to be customized was wrong. By chance I stumbled across org.apache.shiro.concurrent.SubjectAwareExecutorService which does pretty exactly what I want and made me think I could simply provide a custom executor instead of customizing the interceptor. See my answer for details.

推荐答案

我设法实现了我想要的-通过提供扩展版本的 ThreadPoolTask​​Executor :

I managed to achieve what I want - shiro subject is automatically bound and unbound to tasks that are executed by spring's async support - by providing an extended version of the 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 ,该返回器将返回我的自定义执行器:

To make spring use this executor I had to implement an AsyncConfigurer that returns my custom executor:

@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 注释的方法中可用,并且-可能甚至更重要的是-执行该主题后,该主题将与线程分离.异步方法.

With this change the parent Thread's subject will automatically be available in methods that are annotated with @Async and - probably even more important - the subject will be de-attached from the thread after execution of the asynchronous method.

这篇关于自定义/扩展Spring对shiro的@Async支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆