AspectJ - 匹配具有泛型参数的方法的切入点 [英] AspectJ - pointcut to match a method that has generic parameters

查看:29
本文介绍了AspectJ - 匹配具有泛型参数的方法的切入点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是我的通用类和方法:

公共类参数{公共 T 执行(T s){返回 s;}}

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

public static void main(String[] args) {参数<字符串>sp = new Param();String rs = sp.execute("myString");//想要一个关节点参数<布尔值>bp = new Param();布尔 rb = bp.execute(true);//不想要一个关节点}

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

@Pointcut("call(* com.amazon.auiqa.aspectj.generics.Param.execute(**))")无效参数(){}@Pointcut("execution(Object com.amazon.auiqa.aspectj.generics.Param.execute(Object))")无效参数(){}

以下对我不起作用:

 @Pointcut("execution(String com.amazon.auiqa.aspectj.generics.Param.execute(String))")@Pointcut("call(String com.amazon.auiqa.aspectj.generics.Param.execute(String))")

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

解决方案

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

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

I have a generic method that accepts any type as its parameter.
For example, I would like a pointcut that matches the calls made to the method only with 'String' type as its parameter. Ultimately the requirement is to limit the scope which the advices get executed for to 'String' parameters.

Here is my generic class and method:

public class Param<T> {
    public T execute(T s){
        return s;
    }
}

Main class: My app makes calls to the method with both Boolean and String as parameters.

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
}

Below pointcuts are valid for both String and Boolean parameters (work for any type actually). But I would like a pointcut to intercept method calls only when parameter is of type String.

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

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

Below ones did not work for me:

 @Pointcut("execution(String com.amazon.auiqa.aspectj.generics.Param.execute(String))")
 @Pointcut("call(String com.amazon.auiqa.aspectj.generics.Param.execute(String))")

I was wondering if it is possible to achieve what I want to achieve here. I would like to do the same thing with method return types.

解决方案

You cannot do that with AspectJ, nor with any other bytecode manipulation library as generic type information is actually erased from the compiled bytecode (as of Java 9), so your generic method becomes public Object execute(Object s), since the type argument T is unbounded. See Type Erasure at the Java Documentation for further info.

While the original method signature is preserved in the form of metadata, the compiler can check whether type bounds are respected or not while compiling against generic code, but this will not help you in any way to determine what generic type argument an instance of that class was instantiated with, because that information is simply not present at all.

这篇关于AspectJ - 匹配具有泛型参数的方法的切入点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆