如何从带有字节好友的方法描述中获取 Java 方法参数的实际名称?



受本文启发http://mydailyjava.blogspot.com/2022/02/using-byte-buddy-for-proxy-creation.html,我成功地截获了一个方法调用,检查了所有方法参数的值,并返回了一个模拟响应。

但是,我无法获得参数的实际名称(如源代码中所示(。我只能得到诸如";arg0";。

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

@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的回答。在编译器中使用-参数后:

  1. TypeDescription API能够获得实际名称
  2. Java反射API也可以获得实际名称,并带有catch-参数名称只能从用@Origin注释的Method获得,而不能从用@SuperMethod注释的Method中获得
@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];
}
.... ....
}

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

最新更新