Короче говоря, это то, что имена параметров, по-видимому, компилируются, в противном случае вы получили бы исключение, указывающее, что Spring MVC не может определить имя параметра. То есть имена параметров не всегда сохраняются в байт-коде, но, похоже, если они есть, Spring их найдет, если нет, вам нужно указать их при добавлении аннотации @RequestParam
.
Другие подробности доступны по этому подобному вопросу , и это ответов .
В 3.0.5.RELEASE эти аннотации обрабатываются в HandlerMethodInvoker.resolveHandlerArguments и, как представляется, если значение не указано, Spring использует RequestParam.value()
. Это может вернуть пустую строку.
Далее, Spring использует HandlerMethodInvoker.resolveRequestParam
, и там, где имя параметра пусто, он вызывает HandlerMethodINvoker.getRequiredParameterName
с MethodParameter methodParam
в качестве аргумента:
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 }
Обратите внимание, что здесь он пытается извлечь информацию из methodParam
, которая, если мы создадим резервную копию дерева, мы увидим, что resolveHandlerArguments
фактически создает новый MethodParameter
для каждого аргумента, который он процессы. Внутри 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 , мы в конечном итоге вызываем LocalVariableTableParameterNameDiscoverer.ParameterNameDiscoveringVisitor
как часть org.objectweb.asm.ClassReader
, который, насколько я могу судить, пытается прочитать имя параметра вне байт-кода.