如何在运行期获取method中的参数名

Python019

如何在运行期获取method中的参数名,第1张

因为一次在做项目的时候需要扫描接口的信息,其中包括参数名,遇到了点障碍就想着把这个解决方案和问题讲一下。

我们要查看的方法如下

java1.8以后,官方提供了反射的方法能获取到接口的参数名称。示例如下。其中getParameters方法是1.8才开始提供的。并且需要在javac编译时,加上-parameters参数才行。

通过javap -p -v可以查看class的字节码,如下

其中MethodParameters就是1.8后在字节码中记录参数名的地方。但是1.8之前是怎么实现的呢?

spring中有个ParameterNameDiscoverer接口,他有6个实现类。如下:

Aspect开头的都是对增强类的信息获取。我用不到。

PrioritizedParameterNameDiscoverer是一个链表,就是记录一系列的Discoverer。

这个Discoverer就是封装了JDK1.8的getParameters

这个类是重点,它通过asm获取了class文件的LocalVariableTable信息。class,字节码如下:

其中有一行字节码记录了LocalVariableTable信息,LocalVariableTable里不仅保存了参数名,还保存了其他局部变量信息。spring通过slot来判定哪些是参数以及参数的顺序。

但是LocalVariableTable不是类的必须信息,所以不是编译后必须存在的。只有在javac时-g或-g:vars时,才会保存LocalVariableTable信息。

在idea工具中,我们可以通过如下方式,关闭编译时,自动生成LocalVariableTable来尝试查看字节码。

这个Discoverer就是在1.8时多添加了个StandardReflectionParameterNameDiscoverer。

在ParameterNameDiscoverer接口上有这么段注释:

它告诉我们,不是任何时候都能获取到参数名的,只能尝试去获取。

当我们关闭了class debug信息,并且将编译级别设置为1.6时,启动一个简单的spring boot项目。在idea中关闭操作如下:

controller如下:

我们会发现这时候访问该接口传递info参数会报如下错误:

所以,spring mvc中也是有可能获取不到方法参数名的。如果我们需要使用spring mvc的话,最好通过Require等注解来绑定。

Properties props=System getProperties()//系统属性

System out println( Java的运行环境版本 +props getProperty( java version ))

System out println( Java的运行环境供应商 +props getProperty( java vendor ))

System out println( Java供应商的URL +props getProperty( java vendor url ))

System out println( Java的安装路径 +props getProperty( java home ))

System out println( Java的虚拟机规范版本 +props getProperty( java vm specification version ))

System out println( Java的虚拟机规范供应商 +props getProperty( java vm specification vendor ))

System out println( Java的虚拟机规范名称 +props getProperty( java vm specification name ))

System out println( Java的虚拟机实现版本 +props getProperty( java vm version ))

System out println( Java的虚拟机实现供应商 +props getProperty( java vm vendor ))

System out println( Java的虚拟机实现名称 +props getProperty( java vm name ))

System out println( Java运行时环境规范版本 +props getProperty( java specification version ))

System out println( Java运行时环境规范供应商 +props getProperty( java specification vender ))

System out println( Java运行时环境规范名称 +props getProperty( java specification name ))

System out println( Java的类格式版本号 +props getProperty( java class version ))

System out println( Java的类路径 +props getProperty( java class path ))

System out println( 加载库时搜索的路径列表 +props getProperty( java library path ))

System out println( 默认的临时文件路径 +props getProperty( java io tmpdir ))

System out println( 一个或多个扩展目录的路径 +props getProperty( java ext dirs ))

System out println( 操作系统的名称 +props getProperty( os name ))

System out println( 操作系统的构架 +props getProperty( os arch ))

System out println( 操作系统的版本 +props getProperty( os version ))

System out println( 文件分隔符 +props getProperty( file separator ))   //在 unix 系统中是"/"

System out println( 路径分隔符 +props getProperty( path separator ))   //在 unix 系统中是":"

System out println( 行分隔符 +props getProperty( line separator ))   //在 unix 系统中是"/n"

System out println( 用户的账户名称 +props getProperty( user name ))

System out println( 用户的主目录 +props getProperty( user home ))

System out println( 用户的当前工作目录 +props getProperty( user dir ))

lishixinzhi/Article/program/Java/hx/201311/25853