7

我正在使用 Spring 3.x,Java 6。

我有一个带有以下连接点的@Around 方面:

@Around("execution(public * my.service.*.*Connector.*(..))")

所以,我基本上有兴趣拦截对类名以“连接器”结尾的类的公共方法的所有调用。到现在为止还挺好。

现在,就我而言,我想访问方法的实际参数名称:

public doStuff(String myarg, Long anotherArg)

myarg另一个Arg

我了解使用:

CodeSignature signature = (CodeSignature)jointPoint.getSignature();
return signature.getParameterNames();

实际上会起作用,但前提是我使用“ -g ”标志(完整调试)编译代码并且我宁愿不这样做。

有没有其他方法可以访问这种运行时信息。

谢谢 L

4

4 回答 4

8

不幸的是,你不能这样做:-(。这是 JVM/字节码的一个众所周知的限制 - 不能使用反射获得参数名称,因为它们并不总是存储在字节码中(与方法/类名相反) .

作为一种解决方法,几个框架/规范在WebParam( nameproperty) 或PathParam.

目前,没有注释你能得到的只是一个值数组。

于 2011-02-17T15:18:58.197 回答
4

检查org.springframework.core.ParameterNameDiscoverer.

如果未设置@RequestParam,则 spring 使用的注释检查参数名称。value所以@RequestParam String foo实际上会获取名为“foo”的请求参数。它使用ParameterNameDiscoverer机制。我只是不确定使用了哪些实现,通过尝试它们中的每一个。

LocalVariableTableParameterNameDiscoverer读取并使用.classasm 检查名称。

所以,这是可能的。但请确保缓存此信息(例如 - 将参数名称存储在映射中,键 = 类+方法+参数索引)。

但是,正如文档中所述,您需要调试信息。来自以下文档@PathVariable

只有在启用调试的情况下编译代码时,才能将方法参数名称与 URI 模板变量名称匹配。如果未启用调试,则必须在 @PathVariable 注解中指定 URI 模板变量名称的名称,以便将变量名称的解析值绑定到方法参数

因此,如果您真的不想包含该信息,Tomasz Nurkiewicz 的回答解释了解决方法。

于 2011-02-17T15:31:37.250 回答
3

在 Java 8 中有一个新的编译器标志,它允许使用字节码存储额外的元数据,并且可以使用反射中的 Parameter 对象提取这些参数名称。请参阅JDK 8 规范。在较新版本的休眠 org.springframework.core.ParameterNameDiscoverer 中使用此功能。要使用它,请使用javac此标志进行编译:

-parameters                Generate metadata for reflection on method parameters

使用反射的Parameter类访问参数。

于 2014-09-10T00:39:00.030 回答
1

我不确定它是否是最好的方法,但我在我的方法上添加了一个注释:

我的注释:

@Retention (RetentionPolicy.RUNTIME)
@Target (ElementType.METHOD)
public @interface ReadApi
{
    String[] paramNames() default "";
}

@ReadApi (paramNames={"name","id","phone"})
public Address findCustomerInfo(String name, String id, String phone)
{ ..... }

在方面:

@Around("aspect param && @annotation(readApi)")
public Object logParams(ProceedingJoinPoint pjp,
        ReadApi readApi) 
{
    //use pjp.getArgs() and readApi.paramNames();
}

这可能是一个 hack,但我不想编译更多选项来获取信息。无论如何,它对我来说效果很好。唯一的缺点是我需要使注释和方法中的名称保持同步。

于 2017-03-17T15:38:05.667 回答