Spring之运行时获取controller参数名称的方法

先看下面的例子:

package org.reflect;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class MethodName {

    public String hello(String hehe,String haha){
        return "world";
    }

    public static void main(String[] args) {
        Class<MethodName> clz = MethodName.class;
        Method[] methods = clz.getMethods();
        for(int i=0;i<methods.length;i++){
            Method method = methods[i];
            if(method.getName().equals("hello")){
                Parameter[] parameters = method.getParameters();
                //通过debug看到的名称是arg0和arg1。
            }
        }
    }
}

首先需要清楚的认识到,反射不是万能的,不是任何信息都可以获取到的。在上面的代码中,参数名“hehe”和"haha"就不能简单的通过反射获取到。

(但是不是一定无法通过反射获取到,需要编译设置,请参考:https://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html


那么在编译器没有配置的情况下,怎样获取到参数名称呢。

调查时,使用javap命令看到如下信息:

javap -v -l -s -p -c   .class文件路径

  public java.lang.String hello(java.lang.String, java.lang.String);
    descriptor: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=3, args_size=3
         0: ldc           #2                  // String world
         2: areturn
      LineNumberTable:
        line 11: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       3     0  this   Lorg/reflect/MethodName;
            0       3     1  hehe   Ljava/lang/String;
            0       3     2  haha   Ljava/lang/String; 

注意LocalVariableTable这个属性,这个属性下面包含参数名称hehe和haha。也就是说这给程序运行时提供了获取参数名称的方法,其实spring也是使用这种方法获取到的(可以参考LocalVariableTableParameterNameDiscoverer这个spring类调查)。


但是这个属性也不是运行时获取的,它是通过读取.class文件获取到的属性。即如果给程序传递一个Class变量,如org.MyClass,那么程序就会读取org/MyClass.class这个文件,从文件中取得LocalVariableTable这个属性的信息,进而获取到参数名称。

(注意:.class文件包含的信息量和Class变量包含的信息量是不同的,虽然Class变量是由加载.class文件得到的,但是并不代表JVM一定把.class文件里的信息全部加载到内存中或者运行时中)。

注意:

上面提到的两种方法,包括spring,都不是一定能获取到的,如果获取不到,就需要手动在注解里,如@RequestParam里指定映射参数。

参照ParameterNameDiscoverer的javadoc。





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值