AspectJ - 匹配具有泛型参数的方法的切入点

Ram*_*gol 5 java generics aop aspectj spring-aop

我有一个通用方法,它接受任何类型作为其参数。
例如,我想要一个切入点,该切入点仅以“String”类型作为其参数来匹配对方法的调用。最终的要求是将建议执行的范围限制为“字符串”参数。

这是我的通用类和方法:

public class Param<T> {
    public T execute(T s){
        return s;
    }
}
Run Code Online (Sandbox Code Playgroud)

主类:我的应用程序使用布尔值和字符串作为参数调用方法。

public static void main(String[] args) {
    Param<String> sp = new Param<String>();
    String rs = sp.execute("myString"); //want a joint point

    Param<Boolean> bp = new Param<Boolean>();
    Boolean rb = bp.execute(true); //dont want a joint point
}
Run Code Online (Sandbox Code Playgroud)

下面的切入点对 String 和 Boolean 参数都有效(实际上适用于任何类型)。但是我想要一个切入点来拦截方法调用,只有当参数是字符串类型时。

@Pointcut("call(* com.amazon.auiqa.aspectj.generics.Param.execute(**))")
void param(){}

@Pointcut("execution(Object com.amazon.auiqa.aspectj.generics.Param.execute(Object))")
void param(){}
Run Code Online (Sandbox Code Playgroud)

下面的对我不起作用:

 @Pointcut("execution(String com.amazon.auiqa.aspectj.generics.Param.execute(String))")
 @Pointcut("call(String com.amazon.auiqa.aspectj.generics.Param.execute(String))")
Run Code Online (Sandbox Code Playgroud)

我想知道是否有可能在这里实现我想要实现的目标。我想对方法返回类型做同样的事情。

Nán*_*ete 5

你不能用 AspectJ 做到这一点,也不能用任何其他字节码操作库来做,因为泛型类型信息实际上从编译的字节码中删除了(从 Java 9 开始),所以你的泛型方法变成了public Object execute(Object s),因为类型参数T是无界的。有关更多信息,请参阅Java 文档中的类型擦除

虽然原始方法签名以元数据的形式保留,但编译器可以在针对泛型代码进行编译时检查是否遵守类型边界,但这不会以任何方式帮助您确定该类的实例是什么泛型类型参数被实例化,因为该信息根本不存在。