Search code examples
javaspringannotations

How to wrap an annotation and conditionally applies it to a method


Say I have an annotation (@RequiresAccount) introduced in another library and I'm using it in my project, is there a way to conditionally apply it to a method, e.g. apply it when the customer is from website A and not apply when customer is from website B?


Solution

  • I've taken a look and the only possibility I've found was, creating a wrapper-Annotation:

    @Aspect
    @Component
    public class RequiresAccountWrapperAspect {
    
      @Autowired
      private HttpServletRequest request;
    
      private RequiresAccountAspect requiresAccountAspect = new RequiresAccountAspect();
    
      @Around("@annotation(com.example.demo.components.RequiresAccountWrapper)")
      public Object checkIfRequiresAccount(ProceedingJoinPoint joinPoint) throws Throwable {
        String requestURL = request.getRequestURL().toString();
        if (requestURL.startsWith("http://localhost")) {
          requiresAccountAspect.checkAccount(joinPoint);
        }
        return joinPoint.proceed();
      }
    }
    

    So everywhere you've used your RequiresAccount annotation, you can use this wrapper instead. For example:

    @GetMapping("/test")
    @RequiresAccountWrapper
    public String h() {
      return "test";
    }
    

    As you can see I'm creating a new instance of the aspect. I don't know if you have access to the Aspect-class itself but if you have you can then call the method in it and pass the joinPoint. To find the URL from the request you can inject the HttpServletRequest.