복붙노트

[SPRING] 스프링의 @RequestParam 주석 내부 작업

SPRING

스프링의 @RequestParam 주석 내부 작업

Spring에서, 다음 두 문장은, 내가 틀리지 않으면 동일하다.

@RequestParam("type") String type
@RequestParam String type

spring은 'type'(두 번째 버전)의 변수 이름을 어떻게 알 수 있습니까? 나는 그 인상을 받고 있었다. 이 정보는 컴파일하지 않는 한 클래스 파일에서 제거되었습니다. -g 플래그 (디버그 정보 포함).

해결법

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

    1.이것의 짧은 버전은 매개 변수 이름이 컴파일되고있는 것입니다. 그렇지 않다면 Spring MVC가 매개 변수 이름을 추론 할 수 없다는 예외가 발생합니다. 즉, 매개 변수 이름이 바이트 코드에 항상 저장되는 것은 아니지만 Spring의 경우처럼 보이며 그렇지 않으면 @RequestParam 주석을 추가 할 때 매개 변수 이름을 지정해야합니다.

    이것의 짧은 버전은 매개 변수 이름이 컴파일되고있는 것입니다. 그렇지 않다면 Spring MVC가 매개 변수 이름을 추론 할 수 없다는 예외가 발생합니다. 즉, 매개 변수 이름이 바이트 코드에 항상 저장되는 것은 아니지만 Spring의 경우처럼 보이며 그렇지 않으면 @RequestParam 주석을 추가 할 때 매개 변수 이름을 지정해야합니다.

    이와 유사한 질문에 대한 다른 세부 정보가 있으며 답변이 있습니다.

    3.0.5.RELEASE에서 이러한 주석은 HandlerMethodInvoker.resolveHandlerArguments에서 처리되며 값이 제공되지 않으면 Spring은 RequestParam.value ()를 사용합니다. 빈 문자열을 반환 할 수 있습니다.

    아래로 내려 가면 Spring은 HandlerMethodInvoker.resolveRequestParam을 사용하고, 그 안에 매개 변수 이름이 비어 있으면 MethodParameter methodParam을 인자로 사용하여 HandlerMethodINvoker.getRequiredParameterName을 호출합니다.

    718     private String getRequiredParameterName(MethodParameter methodParam) {
    719     String name = methodParam.getParameterName();
    720     if (name == null) {
    721         throw new IllegalStateException(
    722                 "No parameter name specified for argument of type [" + methodParam.getParameterType().getName() +
    723                         "], and no parameter name information found in class file either.");
    724     }
    725     return name;
    726 }
    

    여기서 우리는 트리를 백업 할 때 resolveHandlerArguments가 실제로 처리하는 각 인수에 대해 새 MethodParameter를 만드는 것을 볼 수있는 methodParam에서 정보를 가져 오려고합니다. MethodParameter 내부에서 getParameterName ()을 살펴볼 수 있습니다.

    276 public String getParameterName() {
    277     if (this.parameterNameDiscoverer != null) {
    278         String[] parameterNames = (this.method != null ?
    279                 this.parameterNameDiscoverer.getParameterNames(this.method) :
    280                 this.parameterNameDiscoverer.getParameterNames(this.constructor));
    281         if (parameterNames != null) {
    282             this.parameterName = parameterNames[this.parameterIndex];
    283         }
    284         this.parameterNameDiscoverer = null;
    285     }
    286     return this.parameterName;
    287 }
    

    그래서 이것은 ParameterNameDiscoverer라고 불리는 것을 사용합니다, 그러나 이것은 인터페이스이고 어떤 것이 어떤 구현을 사용하고 있는지 보여주는 것이 아닙니다. LocalVariableTableParameterNameDiscoverer.getParameterNames를 보면 org.objectweb.asm.ClassReader의 일부로 LocalVariableTableParameterNameDiscoverer.ParameterNameDiscoveringVisitor를 호출하게됩니다.이 코드에서 바이트 코드에서 매개 변수 이름을 읽으려고 시도 할 수 있습니다.

  2. from https://stackoverflow.com/questions/6891539/internal-working-of-springss-requestparam-annotation by cc-by-sa and MIT license