2017-10-19 13 views
0

私はSpringの@EnableAsync機能を使用してメソッドを非同期に実行しています。私はApache Shiroを使っています。非同期に実行されるコードでは、非同期呼び出しをトリガしたスレッドに接続されたShiroサブジェクトにアクセスする必要があります。shiroのSpringの@Asyncサポートのカスタマイズ/拡張

史郎が別のスレッドで実行されるCallableを対象に関連付けることによって、別のスレッド内の既存の主題を使用してサポートしています(hereを参照してください):残念ながら

Subject.associateWith(Callable) 

私が直接アクセスすることはできません。このものはSpringによってカプセル化されているのでCallableに移動します。私は、SpringのAnnotationAsyncExecutionInterceptorを拡張して、作成したCallableと私のサブジェクトを関連付ける必要があることを発見しました(これは簡単な部分です)。

問題は、私のカスタムAnnotationAsyncExecutionInterceptorをデフォルトのものの代わりに使用する方法です。既定値はAsyncAnnotationAdvisorAsyncAnnotationBeanPostProcessorに作成されます。もちろんこれらのクラスを拡張することもできますが、これは、Springが自分の拡張クラスを再び使用するようにするために問題にシフトするだけです。

私が欲しいものを達成する方法はありますか?

新しいカスタム非同期アノテーションを追加しても問題ありません。しかし、私はこれが多くの助けになるとは思わない。


UPDATE: は実際にAnnotationAsyncExecutionInterceptorをカスタマイズする必要があるだろうというのが私の発見は間違っていました。偶然、私はorg.apache.shiro.concurrent.SubjectAwareExecutorServiceを見つけました。これは、私が欲しいものをきちんとしてくれて、私は単にインターセプタをカスタマイズするのではなく、カスタム実行者を提供することができたと思いました。詳細は私の答えを見てください。

+0

Callableを返すために、あなたの「非同期メソッド」を書き直すことができます。2.手動で(スプリングで設定されたexecutionPoolで)em off( 'call()') – xerx593

答えて

1

私は私が欲しいものを達成するために管理 - 史郎対象は春の非同期サポートによって実行されるタスクを自動的に結合および非結合である - 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 
} 

この春を使用するようにするにはエグゼキュータ私は私のカスタムエグゼキュータを返す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(); 
    } 
} 

この変更により、親スレッドの件名が自動的にでアノテートされた方法で利用できるようになりますと、おそらくもっと重要なのは、非同期メソッドの実行後にスレッドからスレッドが削除されるということです。

関連する問題