Spring接收前端傳來(lái)的參數(shù)之后,是如何把前端參數(shù)對(duì)應(yīng)到方法里的參數(shù)的?
比如
public String hello(String hello, @RequestParam(value = "world") String world, String end) {
return hello + world + end;
}
這個(gè)方法,假如url是http://localhost:8080/hello?hello=hi&word=spring&end=!
那么spring就可以把hello方法里的hello,world,end一一對(duì)應(yīng)上。world這個(gè)參數(shù)能對(duì)應(yīng)上還可以理解,因?yàn)橛袀€(gè)注解@RequestParam里寫(xiě)了參數(shù)名。
但是hello`,end是如何找到對(duì)應(yīng)參數(shù)的?java在編譯之后他的參數(shù)名就沒(méi)了,spring如何知道第一個(gè)參數(shù)是hello,第三個(gè)參數(shù)是end的?
我問(wèn)題的意思是...spring是如何實(shí)現(xiàn)參數(shù)的對(duì)應(yīng)的?如何知道hello()方法中的參數(shù)'hello,end'這兩個(gè)的參數(shù)名字的,java編譯之后就沒(méi)有參數(shù)名字了
spring對(duì)request參數(shù)做了處理,用request中的參數(shù)去匹配方法的參數(shù),如果name一樣,就會(huì)把值傳過(guò)去,好像是跟順序沒(méi)關(guān)系的,這點(diǎn)你可以試一下。
而你參數(shù)上的注解,是用來(lái)匹配name值不同的情況的,如果請(qǐng)求的參數(shù)名稱和方法參數(shù)名稱不同,就可以用這個(gè)注解。
添加一個(gè)攔截器,在映射這個(gè)方法之前,對(duì)這個(gè)方法進(jìn)行反射處理,獲取方法的參數(shù)及名稱,然后在用發(fā)射調(diào)用這個(gè)方法。差不多是這樣,具體要看spring源碼才能知道。
大家都沒(méi)理解我問(wèn)的問(wèn)題,可能是我提問(wèn)的技巧還不是很好,不過(guò)我已經(jīng)找到答案了。
我想問(wèn)的是假如在Controller里的方法參數(shù)沒(méi)有@RequestParam注解的時(shí)候,Spring是如何通過(guò)反射調(diào)用這個(gè)方法的,因?yàn)閖ava的反射是無(wú)法獲取參數(shù)名字的,無(wú)法獲取參數(shù)名字就以為著無(wú)法把前端傳來(lái)的參數(shù)找到方法中正確的參數(shù)。
現(xiàn)在我找到答案了:
在Spring中的類DefaultParameterNameDiscoverer (<version>2.0.2.RELEASE</version>):
public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer {
private static final boolean kotlinPresent =
ClassUtils.isPresent("kotlin.Unit", DefaultParameterNameDiscoverer.class.getClassLoader());
public DefaultParameterNameDiscoverer() {
if (kotlinPresent) {
addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
}
addDiscoverer(new StandardReflectionParameterNameDiscoverer());
addDiscoverer(new LocalVariableTableParameterNameDiscoverer());
}
}
這個(gè)類是設(shè)置查找參數(shù)名方法的類,這里有三種
1.KotlinReflectionParameterNameDiscoverer:
看代碼是判定是否為Kotlin,如果是就用這種,對(duì)于Kotlin我也不熟就沒(méi)有細(xì)看
2.StandardReflectionParameterNameDiscoverer:
這是用java原生自帶的反射原理獲取參數(shù)名字
private String[] getParameterNames(Parameter[] parameters) {
String[] parameterNames = new String[parameters.length];
for (int i = 0; i < parameters.length; i++) {
Parameter param = parameters[i];
if (!param.isNamePresent()) {
return null;
}
parameterNames[i] = param.getName();
}
return parameterNames;
}
3.LocalVariableTableParameterNameDiscoverer
這是spring通過(guò)asm讀取class字節(jié)碼來(lái)獲取方法的參數(shù)名字,具體的解釋可以查看資料
所以Spring實(shí)際上是通過(guò)反射或者字節(jié)碼讀取獲取方法的參數(shù)的名字的。
另外我這個(gè)Spring的源碼2.0.2.RELEASE,由于2.X.X以上的版本要求jdk環(huán)境是1.8以上。在2.X.X一下的版本DefaultParameterNameDiscoverer類會(huì)先判斷環(huán)境是否是1.8以上,如果是,在會(huì)調(diào)用StandardReflectionParameterNameDiscoverer這個(gè)原生反射查找參數(shù)名的類,因?yàn)檫@個(gè)方法要jdk1.8以后才支持。
北大青鳥(niǎo)APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。