如何将HttpServletRequest注入Spring AOP请求(自定义场景)?

时间:2013-10-09 12:18:56

标签: spring-aop

我知道围绕控制器方法编写AOP建议的标准方法,并且如果在控制器方法中声明,则可以访问HttpServletRequest arg。

但我的情况是我有一个翻译服务,目前是会话范围的,维护用户的翻译语言环境。我觉得这使得服务状态有限,而且我不希望它是会话范围的,因为我认为它确实是Singleton。但是有多个地方调用了翻译服务方法,因此我不想更改签名以在这些方法中添加请求/语言环境。问题是翻译服务方法的所有调用者都无法访问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) { .... } 
}

如果现在,translate的调用者没有HttpServletRequest,我不能在建议中得到请求吗?有解决方法吗?

1 个答案:

答案 0 :(得分:38)

  

我可以围绕翻译服务方法编写一个方面吗?   无论如何,不​​知何故神奇地获得对HttpServletRequest的访问权限   是否可以在来电者的背景下使用?

不容易。实际上,这需要付出很多努力。

简单的方法是依靠RequestContextHolder。在每个请求中,DispatcherServlet将当前HttpServletRequest绑定到static ThreadLocal中的RequestContextHolder对象。您可以在使用

的同一Thread内执行时检索它
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();

您可以使用advice()方法执行此操作,因此无需声明参数。