spring获取方法参数名的方式


原文地址: Java8反射获取方法的参数名称 类和接口

场景:在springmvc中,可以通过请求参数绑定controller方法对应的方法参数名
结论:接口获取不到方法参数名,但普通的类中的方法是可以获取到的

java8反射获取方法的参数名称 类和接口

1.简要说明

  • 演示springboot版本为2.0.3.RELEASE

  • 为啥要分java类和java接口两种进行参数获取的演示

    • java类编译成class文件后,方法签名 和 参数 会保存在字节码文件中,通过一些字节码的解析框架可以获取方法的参数名称

    • java接口编译成class文件后,默认不会保存方法的参数签名,jdk这么设计,因为接口的参数名称一般没有意义,但是现在的技术发展导致一些框架需要用到接口的参数名称

      • spring openFeign 中使用接口进行编程
      • mybatis 中的 Mapper 文件接口
      • 其他一些动态代理接口的编程方式
  • 在Java8之后,反射包package java.lang.reflect;新加入了Parameter类,可以解决这类问题

指导文章 https://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html Java 8 + 增加javac -parameters 参数

大前提:必须是 Java 8

package java.lang.reflect;
...
/**
 * Information about method parameters.
 *
 * A {@code Parameter} provides information about method parameters,
 * including its name and modifiers.  It also provides an alternate
 * means of obtaining attributes for the parameter.
 *
 * @since 1.8
 */
public final class Parameter implements AnnotatedElement {
   

    private final String name;
    private final int modifiers;
    private final Executable executable;
    private final int index;
    ...
}

2.java类获取方法参数名称

测试代码
  • 使用spring中的ParameterNameDiscoverer类获取方法的参数
  • 使用传统的java反射获取参数名称
/**
 * 测试反射获取类方法参数
 */
public class ParameterDemo {
   
    public String say(String message){
   
        return "hello world:"+message;
    }

    public static void main(String[] args) {
   
        Method method = ReflectionUtils.findMethod(ParameterDemo.class,"say",String.class);
        ParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
        String[] parameterNames = discoverer.getParameterNames(method);
        Stream.of(discoverer.getParameterNames(method)).forEach(System.out::println);
        methodTest();
    }

    public static void methodTest() {
   
        Method method = ReflectionUtils.findMethod(ParameterDemo.class,"say",String.class);
        Parameter parameter = method.getParameters()[0];
        System.out.println(parameter.getName());
    }
}

执行结果 在这里插入图片描述

  • spring通过字节码解析技术获取到了方法的参数名称
  • 传统的反射方法无法获取参数名称
解决方法

增加 javac -parameters 参数

通过maven的方式

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.5.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <debug>true</debug>
                <debuglevel>lines,vars,source</debuglevel>
                <compilerArgs>
                    <arg>-parameters</arg>
                </compilerArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

关键代码

<compilerArgs>
     <arg>-parameters</arg>
</compilerArgs>

先 clean 再 compiler 在这里插入图片描述

执行结果

img

3.接口获取方法参数名称

测试代码
/**
 * 测试反射获取接口方法参数
 */
public interface ParameterInterfaceDemo {
   
    String say(String message);

    public static void main(String[] args) {
   
        Method method = ReflectionUtils.findMethod(ParameterInterfaceDemo.class,"say",String.class);
        ParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
        String[] parameterNames = discoverer.getParameterNames(method);
        try {
   
            Stream.of(discoverer.getParameterNames(method)).forEach(System.out::println);
        }catch (Exception e){
   
            e.printStackTrace();
        }
        methodTest();
    }

    public static void methodTest() {
   
        Method method = ReflectionUtils.findMethod(ParameterInterfaceDemo.class,"say",String.class);
        Parameter parameter = method.getParameters()[0];
        System.out.println(parameter.getName());
    }
}
执行结果

在这里插入图片描述

在接口中,不管是spring通过字节码技术还是传统的反射方法都无法获取

解决方法

增加 javac -parameters 参数

通过maven的方式

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.5.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <debug>true</debug>
                <debuglevel>lines,vars,source</debuglevel>
                <compilerArgs>
                    <arg>-parameters</arg>
                </compilerArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

关键代码

<compilerArgs>
     <arg>-parameters</arg>
</compilerArgs>

先 clean 再 compiler img

执行结果
在这里插入图片描述

感谢

mercyblitz - 小马哥的讲解 博客地址 ( https://mercyblitz.github.io)

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值