Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access HttpServletRequest object inside Aspect. Which one is better solution between two solutions mentioned

While trying to get request object in Aspect I found two solutions. I would like to know performance wise which one is better. Here are the details.

I wanted to execute myAspectMethod for all methods annotated by '@myAnnotation'. So where ever spring finds @myAnnotation at method level myAspectMethod will be executed where I am using request object to perform business logic. To get request I found two solutions

  1. Inject request object in Aspect class like
    below

    @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. By sending request object as argument in annotated method and access it thru the argument list received

Access request in 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. Between above two different ways of request object usage which one is better from performance perspective? This is important question for which I would like to know the answer.

  2. What are the other pros and cons of each approach.

like image 531
Siddhant Avatar asked Apr 22 '15 16:04

Siddhant


People also ask

Which method is executed first in AOP?

Executing method on the target class Thus, Spring AOP injects a proxy instead of an actual instance of the target class. When we start the Spring or Spring Boot application, we see Spring executes the advice before the actual method.

Which type of advice allows to access the return value of a JoinPoint?

After (finally) advice: Advice to be executed regardless of the means by which a join point exits (normal or exceptional return). Around advice: Advice that surrounds a join point such as a method invocation. This is the most powerful kind of advice.

Which of the following AOP advice can access and modify arguments of a JoinPoint?

Explanation: An advice can access the current join point information by declaring an argument of type org. aspectj. lang. JoinPoint in the advice method signature.

What is JoinPoint in AOP?

Join Point: A join point is a specific point in the application such as method execution, exception handling, changing object variable values, etc. In Spring AOP a join point is always the execution of a method. Advice: Advices are actions taken for a particular join point.


1 Answers

  1. I'm not sure that the first method works. Even if you can autowire HttpServletRequest this way, you'll have to make your aspect request-scoped.

  2. I think the best option would be to use RequestContextHolder:

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

    This method uses a thread-local storage already populated by Spring and doesn't need any changes in your method signature.

like image 51
axtavt Avatar answered Sep 20 '22 21:09

axtavt