如何使用 Byte Buddy 从方法描述中获取 Java 方法参数的实际名称

受本文http://mydailyjava.blogspot.com/2022/02/using-byte-buddy-for-proxy-creation.html的启发,我设法截取了方法调用,判断了所有方法参数值,并返回了模拟响应.

但是,我无法获得参数的实际名称(与源代码中一样).我只能得到像"arg0"这样的名字.

我所做的最大努力是,在方法匹配器中,我可以访问方法的方法描述,并且我可以获得参数的参数描述.

@Override
public DynamicType.Builder<?> apply(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassFileLocator classFileLocator) {
    logger.info("OiiPlugin processing "+typeDescription);
    return builder
            .method(new ElementMatcher<MethodDescription>() {
                @Override
                public boolean matches(MethodDescription target) {
                    boolean isTarget = target.getDeclaredAnnotations().isAnnotationPresent(MockMe.class);
                    if (isTarget) {
                        ParameterDescription p = target.getParameters().get(0);
                        logger.info(
                                "Parameter 0 NAME:"+p.getActualName()+":"+p.getName()+":"+p.getInternalName());
                    };
                    return isTarget;
                }
            })
            .intercept(MethodDelegation.to(
                    OiiInterceptor.class
            ));
}

但是,它的getActualName()返回空字符串.

[INFO] OiiPlugin processing class com.example.research.oii.client.ExampleClient
[INFO] Parameter 0 NAME::arg0:arg0

我确实通过maven插件配置添加了javac-g:vars参数,以指示javac将参数名称放入.class文件.

    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.0</version>
      <configuration>
        <compilerArgs>
          <arg>-g:vars</arg>
        </compilerArgs>
      </configuration>
    </plugin>

我还能做什么?

谢谢!


发帖备注:

谢谢@Boneill的回答.对编译器使用-PARAMETERS后:

  1. TypeDescription API能够获取实际名称
  2. Java反射API还可以通过Catch获取实际名称-参数名称只能从用@Origin注释的方法获得,而不能从用@SuperMethod注释的方法获得
    @RuntimeType
    public static Object intercept(
            @This Object self,
            @Origin Method method, 
            @AllArguments Object[] args,
            @SuperMethod Method superMethod 
    ) throws Throwable {
        // need to get parameter name from @Origin method, not @SuperMethod
        Parameter[] parameters = method.getParameters(); 
        Object[] mockInterceptionParameters = new Object[parameters.length*2];
        for (int i=0; i<parameters.length; i++) {
            Parameter p = parameters[i];
            mockInterceptionParameters[i*2] = p.getName();
            mockInterceptionParameters[i*2+1] = args[i];
        }
        .... ....
    }

java byte-buddy

推荐答案

您需要将-parameters参数传递给Java编译器.-g:vars参数提供有关所有局部变量的信息,但定义该变量的属性永远不能使用反射API访问.当使用-parameters时,将使用一个明确设计用于由反射API访问的特殊属性.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值