コントローラーメソッドに関するAOPアドバイスを作成する標準的な方法を知っています。コントローラーメソッドで宣言されている場合は、HttpServletRequest引数にアクセスできます。
しかし、私のシナリオでは、翻訳サービスがあります。これは現在、翻訳用のユーザーのロケールを維持するセッションスコープです。これによりサービスがステートフルになると思います。また、実際にはシングルトンだと思うので、セッションスコープにしたくありません。ただし、翻訳サービスメソッドが呼び出される場所は複数あるため、これらのメソッドにリクエスト/ロケールを追加するために署名を変更したくありません。問題は、翻訳サービスのメソッドのすべての呼び出し元がHttpServletRequest(コントローラーメソッドではない)にアクセスできないことです。翻訳サービスメソッドに関するアスペクトを記述して、呼び出し元のコンテキストで使用可能かどうかに関係なく、どういうわけか魔法のようにHttpServletRequestにアクセスできますか?
@Service
public class TranslationService {
public void translate(String key) {
...
}
}
@Aspect
@Component
public class LocaleFinder {
@PointCut("execution(* TranslationService.translate(..))")
private void fetchLocale() {}
@Around("fetchLocale()") // in parameter list
public void advice(JoinPoint joinpoint, HttpServletRequest request) { .... }
}
今、翻訳の呼び出し元がHttpServletRequestを持っていない場合、アドバイスでリクエストを受け取ることはできませんか?回避策はありますか?
翻訳サービスメソッドに関するアスペクトを記述して、呼び出し元のコンテキストで使用可能かどうかに関係なく、どういうわけか魔法のようにHttpServletRequestにアクセスできますか?
簡単ではありません。実際、それは多くの努力を必要とするでしょう。
これを行う簡単な方法は、RequestContextHolder
に依存することです。すべてのリクエストで、DispatcherServlet
は現在のHttpServletRequest
をRequestContextHolder
内の_static ThreadLocal
_オブジェクトにバインドします。同じThread
内で実行するときに取得できます
_HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
_
これはadvice()
メソッドで実行できるため、パラメーターを宣言する必要はありません。