java - Spring AOP - ProceedingJoinpoint - MethodSignature 向下转型

标签 java spring aspectj spring-aop

有没有办法从 ProceedingJoinPoint 获取 MethodSignature 而无需向下转型?

    private String toEventString(ProceedingJoinPoint pjp) {
    MethodSignature methodSignature = ((MethodSignature)pjp.getSignature());

    StringBuilder sb = new StringBuilder();

    String[] paramNames = methodSignature.getParameterNames();
    Class[] paramTypes = methodSignature.getParameterTypes();

    sb.append(methodSignature.getName()).append('(');

    for(int i = 0; i < paramNames.length; i++) {
        sb
            .append(paramTypes[i].getSimpleName())
            .append(" ")
            .append(paramNames[i]);
        if(i < paramNames.length - 1) {
            sb.append(", ");
        }
    }

    return sb.append(" )").toString();

}

最佳答案

简单的问题,简单的答案:不。

更新:也许您想知道为什么需要转换。除了方法签名之外还有其他签名类型吗?哦,是的,有。例如。如果您使用 within(SomeClass) 您可能会遇到以下任何签名类型:

  • 方法
  • 构造函数
  • 类初始值设定项
  • 字段
  • 建议执行
  • catch子句
  • 锁定/解锁(一种相当特殊的情况,如果使用 -Xjoinpoints:synchronization 编译方面,则捕获同步块(synchronized block))

这是一个小例子:

驱动程序应用程序:

package de.scrum_master.app;

public class Application {
  private String name;

  public Application(String name) {
    this.name = name;
  }

  public static void main(String[] args) {
    Application application = new Application("my app");
    synchronized (application) {
      try {
        application.doSomething("foo", 11, false);
      }
      catch (RuntimeException e) {}
    }
  }

  private void doSomething(String string, int i, boolean b) {
    throw new RuntimeException("oops");
  }
}

应拦截的建议执行方面:

package de.scrum_master.aspect;

public aspect MyOtherAspect {
  before() : execution(* main(..)) {}
}

方面打印签名类型:

package de.scrum_master.aspect;

import de.scrum_master.app.Application;

public aspect MyAspect {
  before() : within(Application) || within(MyOtherAspect) {
    System.out.println(thisJoinPoint);
    System.out.println("    " + thisJoinPoint.getSignature().getClass().getSimpleName());
  }
}

控制台日志:

staticinitialization(de.scrum_master.app.Application.<clinit>)
    InitializerSignatureImpl
staticinitialization(de.scrum_master.aspect.MyOtherAspect.<clinit>)
    InitializerSignatureImpl
preinitialization(de.scrum_master.aspect.MyOtherAspect())
    ConstructorSignatureImpl
initialization(de.scrum_master.aspect.MyOtherAspect())
    ConstructorSignatureImpl
execution(de.scrum_master.aspect.MyOtherAspect())
    ConstructorSignatureImpl
adviceexecution(void de.scrum_master.aspect.MyOtherAspect.before())
    AdviceSignatureImpl
execution(void de.scrum_master.app.Application.main(String[]))
    MethodSignatureImpl
call(de.scrum_master.app.Application(String))
    ConstructorSignatureImpl
preinitialization(de.scrum_master.app.Application(String))
    ConstructorSignatureImpl
initialization(de.scrum_master.app.Application(String))
    ConstructorSignatureImpl
execution(de.scrum_master.app.Application(String))
    ConstructorSignatureImpl
set(String de.scrum_master.app.Application.name)
    FieldSignatureImpl
lock(lock(Object))
    LockSignatureImpl
call(void de.scrum_master.app.Application.doSomething(String, int, boolean))
    MethodSignatureImpl
execution(void de.scrum_master.app.Application.doSomething(String, int, boolean))
    MethodSignatureImpl
call(java.lang.RuntimeException(String))
    ConstructorSignatureImpl
handler(catch(RuntimeException))
    CatchClauseSignatureImpl
unlock(unlock(Object))
    UnlockSignatureImpl

顺便说一句,每个 *Impl 类都实现了相应的签名接口(interface)。

关于java - Spring AOP - ProceedingJoinpoint - MethodSignature 向下转型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42499089/

相关文章:

java - 每个线程的方面和每个线程组的方面

java - 让aspectj与scala模型一起工作

java - 如何使方法返回类型作为AspectJ ITD中的当前类型?

java - 在 web 服务本身 axis2 中使用资源?

java - 在 bean 构建中使用 Spring @Value

Java:Spring-MVC:导出和导入 Microsoft Excel 的最简单方法?

java - Spring 应用程序最简单的 main() 方法是什么?

java - 在android中运行一个可执行jar

Java不发送HTTP POST请求

java - Maven:用于手动测试的源文件夹