In general, it is difficult to get the parameter name by reflection, only the argument type, because at compile time, the parameter name is likely to change, you need to add parameters at compile time will not change.
The use of annotations is possible to implement the name of the type (or the name of the annotation), but it is not convenient to write annotations.
Observing the data binding in the Spring MVC framework, we found that it was possible to directly bind the corresponding parameter in the HTTP request to the corresponding parameter name, how did he do it?
First, refer to the principle of automatic binding: Spring Source Research: Data binding
In the Getmethodargumentvalues method, methodparameter[] Parameters = Getmethodparameters (); This sentence takes all the parameters of the method, The Methodparameter type has the property of the method name, what is this class?
is a class in the spring core, and Org.springframework.core.MethodParameter is not implemented by reflection.
Method Getmethodparameters () is in the class of Handlermethod
Public methodparameter[] Getmethodparameters () { returnthis. Parameters; }
The this.parameters is initialized in the constructor method:
Public Handlermethod (Object bean, method) { "bean is required"); " Method is required "); this. Bean = Bean; This NULL ; this. Method = method; this. Bridgedmethod = Bridgemethodresolver.findbridgedmethod (method); this. Parameters = initmethodparameters (); }
Initmethodparameters () generates a list of parameters.
Private methodparameter[] Initmethodparameters () { intthis. Bridgedmethod.getparametertypes (). length; New Methodparameter[count]; for (int i = 0; i < count; i++) { new handlermethodparameter (i); } return result; }
Handlermethodparameter (i) is the inner class of Handlermethod, inherited from Methodparameter
To construct a method call:
Public Handlermethodparameter (int index) { Super(Handlermethod. this. Bridgedmethod, index); }
Then call the constructor of the Methodparameter class:
Public int int nestinglevel) { "Method must not is null"); this. Method = method; this. Parameterindex = parameterindex; this. nestinglevel = nestinglevel; This NULL ; }
There is a private String parametername in the Methodparameter class, and the parameter name is stored, but the constructor does not set his value, and the value is actually set in:
PublicString Getparametername () {if( This. parameternamediscoverer! =NULL) {string[] parameternames= ( This. Method! =NULL? This. Parameternamediscoverer.getparameternames ( This. method): This. Parameternamediscoverer.getparameternames ( This. constructor)); if(Parameternames! =NULL) { This. parametername = parameternames[ This. Parameterindex]; } This. Parameternamediscoverer =NULL; } return This. parametername; }
So how do you store parameter names in this class?
Reflection gets the name of a parameter in a method (not a type)