在Spring中,以下兩個語句是,如果我沒有記錯的話,相同的:泉@RequestParam標註的內部工作
@RequestParam("type") String type
@RequestParam String type
怎樣才能知道春天「類型」(第二版)的變量名。我的印象是 ,這個信息已從類文件中刪除,除非使用-g標誌(包括調試信息)編譯爲 。
在Spring中,以下兩個語句是,如果我沒有記錯的話,相同的:泉@RequestParam標註的內部工作
@RequestParam("type") String type
@RequestParam String type
怎樣才能知道春天「類型」(第二版)的變量名。我的印象是 ,這個信息已從類文件中刪除,除非使用-g標誌(包括調試信息)編譯爲 。
這個簡短版本顯然是在編譯參數名稱,如果它們不是,你會得到一個異常,表明Spring MVC無法推斷出參數名稱。也就是說,參數名並不總是存儲在字節碼中,但看起來像是如果它們是,Spring會找到它們,如果不是,則需要在添加@RequestParam
註釋時指定它們。
其他細節可在此similar question和它的answers。
在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 }
請注意,在這裏它試圖從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
,但是這是一個界面,我的跟蹤沒有顯示它是一個使用的實施,有few。看看LocalVariableTableParameterNameDiscoverer.getParameterNames我們最終調用LocalVariableTableParameterNameDiscoverer.ParameterNameDiscoveringVisitor
作爲org.objectweb.asm.ClassReader
的一部分,就我所知,它試圖從字節碼中讀取參數名稱。
題外話,但(LocalVariableTableParameterNameDiscoverer.ParameterNameDiscoveringVisitor)真的是相當類似的名字去的樣本。 –