Spring AOP - ProceedingJoinpoint - MethodSignature 向下转换
Spring AOP - ProceedingJoinpoint - MethodSignature Downcast
有没有办法在不向下转换的情况下从 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)
,您可能会遇到以下任何签名类型:
- 方法
- 构造函数
- class 初始化程序
- 字段
- 建议执行
- catch 子句
- 锁定/解锁(一种相当特殊的情况,如果使用
-Xjoinpoints:synchronization
编译方面,则捕获同步块)
这是一个小例子:
驱动申请:
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
classes 都实现了相应的签名接口。
有没有办法在不向下转换的情况下从 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)
,您可能会遇到以下任何签名类型:
- 方法
- 构造函数
- class 初始化程序
- 字段
- 建议执行
- catch 子句
- 锁定/解锁(一种相当特殊的情况,如果使用
-Xjoinpoints:synchronization
编译方面,则捕获同步块)
这是一个小例子:
驱动申请:
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
classes 都实现了相应的签名接口。