Spring 中 java 获取方法参数名称

来源:互联网 发布:淘宝vr眼镜效果怎么样 编辑:程序博客网 时间:2024/06/05 23:43

一、介绍

在学习Spring ioc的时候,我们可以在Spring配置文件中 对 对象构造器方法和实例方法按参数名称进行注入,在我以前学习使用的时候,并没有感觉有啥困难的,也一直以为java反射能够获取到方法的参数名称,
但是在我简单(spring ioc的源码细节太多了,有很多看不懂)看了spring ioc源码的部分时,发现Spring通过定义ParameterNameDiscoverer接口,来定义获取参数名称的方法,
这里写图片描述

它的实现类:
这里写图片描述

其中AspectJ相关的ParameterNameDiscover实现类源码并没有看,准备学习到AOP的时候在来看。

二、获取参数名称的策略

1、使用jdk8,在jdk8中扩充的反射的API,在jdk8中提供了一个新的抽象类Executable,该类提供了getParameters()方法,该方法可以用来获取方法的参数名称,并且Method和Constructor都继承了Executable。

这里写图片描述

2、使用字节码框架,读取每个方法栈帧中的局部变量表,来获取方法参数的名称。     Spring使用ASM字节码操作框架来获取方法参数的名称。  使用ASM字节码框架,读取类的class文件。ASM框架底层已经将class文件处理好,我们通过继承  ClassVisitor和MethodVisitor,并重写部分方法,即可获取到参数名称。     Spring中定义了LocalVariableTableParameterNameDiscoverer来实现这一过程,下面让我们来  看看该类的源码。

这里写图片描述

该类实现了ParameterNameDiscover接口中定义的2个方法,分别对Method和Constructor方法进行处理。并且将实际获取参数名称的实现转交给inspectClass方法统一实现。

这里写图片描述

inspectClass方法中主要步骤如下:    1、以字节流的形式读取class文件    2、使用ASM的ClassReader处理解析class文件,并产生事件    3、ClassReader.accept接受一个ClassVisitor(ParameterNameDiscoveringVistor)来消      费ClassReader产生的事件

这里写图片描述

ClassVisitor中定义了一些方法来处理与之对应的Class文件中的各个部分,Class文件结构分为以下几个部分:

这里写图片描述
而VisitMethod方法则是对应Class文件中的方法表集合,visitMehod方法会返回一个MethodVisitor用
来处理Class文件中方法表集合中的每个方法,如果我们要获取方法参数名称,则需要自定
义MethodVisitor的部分实现。

这里写图片描述

这里有一点漏讲了,在computeLvtSlotIndices()方法中有个Type[]类型的paramTypes(其中Type类型应该是ASM框架里的类型),而computeLvtSlotIndices()方法在构造器中被调用,在LocalVariableTableVisitor构造函数中parmTypes由Type.getArgumentTypes(desc)产生那么这个构造函数中的desc参数到底是什么尼?其实你去看下,介绍Class字节码结构的书籍就知道了(主要看下字段表集合和方法表集合)

这里写图片描述

这里写图片描述

在字段表和方法表中有个descriptor_index,它是描述符,
对于字段:用来描述字段类型
对于方法:用来描述参数列表和返回值
比如一个java类型 String[][] a; 则被描述为:[[Ljava/lang/String;
比如一个java方法 public String[][] get(String[] str,int name),则被描述为:
( [[Ljava/lang/String;I)[[Ljava/lang/String;

其对应关系如图:
这里写图片描述

多维数组则对应多个 [

LocalVariableTableVisitor构造函数参数中的desc就是方法表的描述符,而Type.getArgumentTypes(desc)则就是简单的解析这个描述符的方法而已

到此结束
对于ASM字节码框架,我只是简单学习了下,大概学习了如何从中获取,对于通过ASM生成字节码还没有这个水平。
对于字节码结构的熟悉程度:只能算了解,需要去查。
而这些:对于我这个业务程序员来说:如果不改变,永远都用不到,真是可悲。

原创粉丝点击