복붙노트

[SPRING] Spring 컨트롤러에서 AOP 조언을 통해 RequestMapping 요청을 얻는 방법은 무엇입니까?

SPRING

Spring 컨트롤러에서 AOP 조언을 통해 RequestMapping 요청을 얻는 방법은 무엇입니까?

요청 매핑을 가진 어떤 종류의 컨트롤러가 주어진다.

@RequestMapping(value="/some/path", method=RequestMethod.POST)

애스펙트 클래스에서 메서드 값 (RequestMethod.POST)을 어떻게 가져올 것입니까?

POST 요청을 수행하는 모든 컨트롤러 메서드를 추적하고 싶습니다.

감사

해결법

  1. ==============================

    1.@ AL13N : 자신의 대답은 정확하지만 주석을 매개 변수에 바인딩하는 경우 리플렉션을 사용할 필요가 없습니다. 다음은 POJO + AspectJ의 예제이다. Spring AOP에서는 동일해야한다.

    @ AL13N : 자신의 대답은 정확하지만 주석을 매개 변수에 바인딩하는 경우 리플렉션을 사용할 필요가 없습니다. 다음은 POJO + AspectJ의 예제이다. Spring AOP에서는 동일해야한다.

    main 메소드가있는 샘플 컨트롤러 :

    package de.scrum_master.app;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    @Controller
    public class MyController {
        @RequestMapping(value="/some/path", method=RequestMethod.POST)
        public void foo() {
            System.out.println("foo");
        }
        public void bar() {
            System.out.println("bar");
        }
    
        public static void main(String[] args) {
            MyController controller = new MyController();
            controller.foo();
            controller.bar();
        }
    }
    

    양상:

    package de.scrum_master.aspect;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    public aspect RequestMappingInterceptor {
        @Pointcut(
            "within(@org.springframework.stereotype.Controller *) && " +
            "@annotation(requestMapping) && " +
            "execution(* *(..))"
        )
        public void controller(RequestMapping requestMapping) {}
    
        @Before("controller(requestMapping)")
        public void advice(JoinPoint thisJoinPoint, RequestMapping requestMapping) {
            System.out.println(thisJoinPoint);
            System.out.println("  " + requestMapping);
            System.out.println("  " + requestMapping.method()[0]);
        }
    }
    

    BTW, Pointcut의 && execution (* * (..)) 부분은 Spring AOP에서 필요하지 않을 것입니다. 왜냐하면 그것은 실행 pointcut을 알고 있기 때문입니다. AspectJ에서는 더 강력하기 때문에 call () 및 다른 유형의 pointcut을 제외해야합니다. 그것은 상처를주지 않으며 더 안전하고 더 명백합니다.

    콘솔 출력 :

    execution(void de.scrum_master.app.MyController.foo())
      @org.springframework.web.bind.annotation.RequestMapping(headers=[], name=, value=[/some/path], produces=[], method=[POST], params=[], consumes=[])
      POST
    foo
    bar
    

    편집 : AspectJ가하지 않는 동안 Spring AOP가이 순서를 주장하는 것처럼 보이기 때문에 joinpoint를 첫 번째 advice 메소드 매개 변수로 만들기 위해 매개 변수를 바꿨다.

  2. ==============================

    2.해결책을 찾았습니다.

    해결책을 찾았습니다.

    import org.aspectj.lang.reflect.MethodSignature;
    import java.lang.reflect.Method;
    
    @Pointcut("within(@org.springframework.stereotype.Controller *)")
    public void controller() {}
    
    // In advice
    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
    Method method = methodSignature .getMethod();
    RequestMethod[] requestMethods = method.getAnnotation(RequestMapping.class).method();
    

    가져올 클래스를주의하십시오.

  3. from https://stackoverflow.com/questions/26933623/how-do-you-get-requestmapping-request-in-aop-advice-from-a-spring-controller by cc-by-sa and MIT license