【问题标题】:Access HttpServletRequest object inside Aspect. Which one is better solution between two solutions mentioned在 Aspect 中访问 HttpServletRequest 对象。在提到的两种解决方案之间,哪一种是更好的解决方案
【发布时间】:2019-11-13 14:12:59
【问题描述】:

在尝试在 Aspect 中获取请求对象时,我找到了两个解决方案。我想知道性能方面哪个更好。以下是详细信息。

我想为所有由“@myAnnotation”注释的方法执行 myAspectMethod。因此,只要 spring 在方法级别找到 @myAnnotation,myAspectMethod 就会在我使用请求对象执行业务逻辑的地方执行。为了得到请求,我找到了两个解决方案

  1. 在 Aspect 类中注入请求对象,例如
    下面

    @Aspect 
    public class MyAspect {
    @Autowired(required = true)
    **private HttpServletRequest request;**
    @Around("@annotation(myAnnotation)")
    public Object myAspectMethod(ProceedingJoinPoint pjp,  
            MyAnnotation myAnnotation) throws Throwable {
            //....do something with request object
            }
    }
    
  2. 通过在带注释的方法中将请求对象作为参数发送并通过收到的参数列表访问它

Aspect 中的访问请求

@RequestMapping(method = { RequestMethod.GET }, value = "/something")
@MyAnnotation
public Object myAnnotatedMethod(**HttpServletRequest request**)
{
//....some business logic
}

@Aspect
public class MyAspect {
@Around("@annotation(myAnnotation)")
    public Object myAspectMethod(ProceedingJoinPoint pjp,
            MyAnnotation myAnnotation) throws Throwable {
            HttpServletRequest request = getRequestArgument(pjp);
            ....do something with request object
            }
    private HttpServletRequest getRequestArgument(ProceedingJoinPoint pjp) {
        for (Object object : pjp.getArgs()) {
            if (object instanceof HttpServletRequest) {
                return (HttpServletRequest) object;
            }
        }
        return null;
    }
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
}
  1. 在以上两种不同的请求对象使用方式之间,从性能角度来看,哪一种更好?这是一个重要的问题,我想知道答案。

  2. 每种方法的其他优缺点是什么。

【问题讨论】:

    标签: java spring performance aop


    【解决方案1】:
    1. 我不确定第一种方法是否有效。即使您可以通过这种方式自动装配HttpServletRequest,您也必须将方面设置为请求范围。

    2. 我认为最好的选择是使用RequestContextHolder

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

      此方法使用 Spring 已填充的线程本地存储,不需要对方法签名进行任何更改。

    【讨论】:

    • 谢谢@axtavt!对于解决方案#1,我想到了类似的东西,即如何将请求对象注入单例方面。当我实现并传递具有不同标头值的不同请求时,每次我都会得到预期值。这意味着每个请求对象都可以设置为单例 bean。看起来 Spring 根据范围优雅地处理它。这是我遇到的优秀文章 [docs.spring.io/spring/docs/4.0.x/spring-framework-reference/…
    • 在方面,我想制定/更改/更新 Http Post 请求。我该怎么做?
    【解决方案2】:

    第一种方法无效。

    @Autowired(required = true)
    private HttpServletRequest request;
    

    确实有请求特定的数据。

    我目前正在使用以下内容从我的请求中提取自定义标头

    HttpServletRequest request = ((ServletRequestAttributes) 
    RequestContextHolder.currentRequestAttributes()).getRequest();
    request.getHeader("mycustom");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-02
      • 2012-02-07
      • 1970-01-01
      • 1970-01-01
      • 2012-02-15
      • 2015-05-11
      • 1970-01-01
      相关资源
      最近更新 更多