我知道围绕控制器方法编写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,我能否在建议中获取请求?有解决方法吗?

最佳答案

我可以围绕翻译服务方法写一个方面吗?
无论如何,魔术般地获得对HttpServletRequest的访问
是否可以在调用者的上下文中使用?


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

最简单的方法是依靠RequestContextHolder。在每个请求中,DispatcherServlet将当前HttpServletRequest绑定到static ThreadLocal中的RequestContextHolder对象。您可以在与Thread相同的advice()中执行时检索它

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();


您可以在方法中执行此操作,因此无需声明参数。

关于spring-aop - 如何将HttpServletRequest注入(inject)Spring AOP请求(自定义方案)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19271807/

10-12 03:57