嵌套泛型上的AspectJ切入点?

问题描述

我上了这个课:

public final class Helper<T> {

   public static <TYPE> Helper.Builder<TYPE> builder(final Class<TYPE> objectClass) {
        return new Helper.Builder<>(objectClass);
   }

   public static final class Builder<E> {

      private String name;

      public Builder<E> withName(final String name) {
         this.name = name;
         return this
      }
   }
}

我试图像这样创建一个拦截器:

@Around("execution(* com.test.Helper.Builder.withName(String,..))")
public Object interceptor(ProceedingJoinPoint jp) throws Throwable {
   System.out.println("intercepted!");
   return joinPoint.proceed(joinPoint.getArgs());
}

我尝试对此进行测试,以查看输出是否得到打印:

public class Dummy {}

Helper<Dummy> helper = Helper
   .builder(Dummy.class)
   .withName("name")

但是我的拦截器从未被调用。我已确保该软件包正确无误,并且可以在没有泛型的其他类上使用它。我在线阅读并尝试将切入点修改"execution(* com.test.Helper+.Builder+.withName(String,..))",但出现语法错误

Invalid pointcut 'execution(* com.test.Helper+.Builder+.withName(String,..))':
  org.aspectj.weaver.patterns.ParserException

这是怎么回事?

edit:对于可能有相同错误的任何人,问题实际上是版本。我已从Aspectjweaver 1.6.2升级到1.8,并且工作正常。

解决方法

TL; DR :这是一条红鲱鱼……

Invalid pointcut 'execution(* com.test.Helper+.Builder+.withName(String,..))':
  org.aspectj.weaver.patterns.ParserException

冗长的版本

发生了什么事?

示例代码中发生的太多事情在语法上是非法的。因此,我将把最严重的违法行为绳之以法。

您定义 Builder 以返回 Builder

Builder< E > withName( … ) {
    … 
    return this;
}

但是您尝试将其分配给 {strong> not Builder ...

…
Helper<Dummy> helper = Helper
   .builder(Dummy.class)
   .withName("name")
…
除了

AspectJ,here is a syntactically-legal demonstration of how I propose还在 之前实现了 Helper >

…
public class Helper { 
    
    public static < C > Helper.Builder< C > builder( final Class< C > objectClass ) { 
        
        return new Helper.Builder< C >( objectClass );
    }
    
    public static class Builder< D > { 
        
        private String name;
        
        private Class< D > objectClass;
        
        public Builder( Class< D > objectClass ) { this.objectClass = objectClass; }
        
        public Builder< D > withClass( final String name ) { this.name = name; return this;  }
    }
}

I demonstrate experimentally that the above implementation成功编译。这演示了正确的调用方式……

…
Helper.Builder builder = Helper.builder( DeduperAnswer.class ).withClass( "foo" );
…