|
|
|
@ -58,196 +58,6 @@ public class AdviceWeaver extends ClassVisitor implements Opcodes {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 方法开始<br/>
|
|
|
|
|
* 用于编织通知器,外部不会直接调用
|
|
|
|
|
*
|
|
|
|
|
* @param loader 类加载器
|
|
|
|
|
* @param adviceId 通知ID
|
|
|
|
|
* @param className 类名
|
|
|
|
|
* @param methodName 方法名
|
|
|
|
|
* @param methodDesc 方法描述
|
|
|
|
|
* @param target 返回结果
|
|
|
|
|
* 若为无返回值方法(void),则为null
|
|
|
|
|
* @param args 参数列表
|
|
|
|
|
*/
|
|
|
|
|
public static void methodOnBegin(
|
|
|
|
|
int adviceId,
|
|
|
|
|
ClassLoader loader, String className, String methodName, String methodDesc,
|
|
|
|
|
Object target, Object[] args) {
|
|
|
|
|
|
|
|
|
|
if (isSelfCallRef.get()) {
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
isSelfCallRef.set(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 构建执行帧栈,保护当前的执行现场
|
|
|
|
|
final GaStack<Object> frameStack = new ThreadUnsafeFixGaStack<Object>(FRAME_STACK_SIZE);
|
|
|
|
|
frameStack.push(loader);
|
|
|
|
|
frameStack.push(className);
|
|
|
|
|
frameStack.push(methodName);
|
|
|
|
|
frameStack.push(methodDesc);
|
|
|
|
|
frameStack.push(target);
|
|
|
|
|
frameStack.push(args);
|
|
|
|
|
|
|
|
|
|
final AdviceListener listener = getListener(adviceId);
|
|
|
|
|
frameStack.push(listener);
|
|
|
|
|
|
|
|
|
|
// 获取通知器并做前置通知
|
|
|
|
|
before(listener, loader, className, methodName, methodDesc, target, args);
|
|
|
|
|
|
|
|
|
|
// 保护当前执行帧栈,压入线程帧栈
|
|
|
|
|
threadFrameStackPush(frameStack);
|
|
|
|
|
} finally {
|
|
|
|
|
isSelfCallRef.set(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 方法以返回结束<br/>
|
|
|
|
|
* 用于编织通知器,外部不会直接调用
|
|
|
|
|
*
|
|
|
|
|
* @param returnObject 返回对象
|
|
|
|
|
* 若目标为静态方法,则为null
|
|
|
|
|
*/
|
|
|
|
|
public static void methodOnReturnEnd(Object returnObject) {
|
|
|
|
|
methodOnEnd(false, returnObject);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 方法以抛异常结束<br/>
|
|
|
|
|
* 用于编织通知器,外部不会直接调用
|
|
|
|
|
*
|
|
|
|
|
* @param throwable 抛出异常
|
|
|
|
|
*/
|
|
|
|
|
public static void methodOnThrowingEnd(Throwable throwable) {
|
|
|
|
|
methodOnEnd(true, throwable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 所有的返回都统一处理
|
|
|
|
|
*
|
|
|
|
|
* @param isThrowing 标记正常返回结束还是抛出异常结束
|
|
|
|
|
* @param returnOrThrowable 正常返回或者抛出异常对象
|
|
|
|
|
*/
|
|
|
|
|
private static void methodOnEnd(boolean isThrowing, Object returnOrThrowable) {
|
|
|
|
|
|
|
|
|
|
if (isSelfCallRef.get()) {
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
isSelfCallRef.set(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 弹射线程帧栈,恢复Begin所保护的执行帧栈
|
|
|
|
|
final GaStack<Object> frameStack = threadFrameStackPop();
|
|
|
|
|
|
|
|
|
|
// 弹射执行帧栈,恢复Begin所保护的现场
|
|
|
|
|
final AdviceListener listener = (AdviceListener) frameStack.pop();
|
|
|
|
|
final Object[] args = (Object[]) frameStack.pop();
|
|
|
|
|
final Object target = frameStack.pop();
|
|
|
|
|
final String methodDesc = (String) frameStack.pop();
|
|
|
|
|
final String methodName = (String) frameStack.pop();
|
|
|
|
|
final String className = (String) frameStack.pop();
|
|
|
|
|
final ClassLoader loader = (ClassLoader) frameStack.pop();
|
|
|
|
|
|
|
|
|
|
// 异常通知
|
|
|
|
|
if (isThrowing) {
|
|
|
|
|
afterThrowing(listener, loader, className, methodName, methodDesc, target, args, (Throwable) returnOrThrowable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回通知
|
|
|
|
|
else {
|
|
|
|
|
afterReturning(listener, loader, className, methodName, methodDesc, target, args, returnOrThrowable);
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
isSelfCallRef.set(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 方法内部调用开始
|
|
|
|
|
*
|
|
|
|
|
* @param adviceId 通知ID
|
|
|
|
|
* @param owner 调用类名
|
|
|
|
|
* @param name 调用方法名
|
|
|
|
|
* @param desc 调用方法描述
|
|
|
|
|
*/
|
|
|
|
|
public static void methodOnInvokeBeforeTracing(int adviceId, String owner, String name, String desc, int lineNumber) {
|
|
|
|
|
final InvokeTraceable listener = (InvokeTraceable) getListener(adviceId);
|
|
|
|
|
if (null != listener) {
|
|
|
|
|
try {
|
|
|
|
|
listener.invokeBeforeTracing(owner, name, desc, lineNumber);
|
|
|
|
|
} catch (Throwable t) {
|
|
|
|
|
logger.warn("advice before tracing failed.", t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 方法内部调用结束(正常返回)
|
|
|
|
|
*
|
|
|
|
|
* @param adviceId 通知ID
|
|
|
|
|
* @param owner 调用类名
|
|
|
|
|
* @param name 调用方法名
|
|
|
|
|
* @param desc 调用方法描述
|
|
|
|
|
*/
|
|
|
|
|
public static void methodOnInvokeAfterTracing(int adviceId, String owner, String name, String desc, int lineNumber) {
|
|
|
|
|
final InvokeTraceable listener = (InvokeTraceable) getListener(adviceId);
|
|
|
|
|
if (null != listener) {
|
|
|
|
|
try {
|
|
|
|
|
listener.invokeAfterTracing(owner, name, desc, lineNumber);
|
|
|
|
|
} catch (Throwable t) {
|
|
|
|
|
logger.warn("advice after tracing failed.", t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 方法内部调用结束(异常返回)
|
|
|
|
|
*
|
|
|
|
|
* @param adviceId 通知ID
|
|
|
|
|
* @param owner 调用类名
|
|
|
|
|
* @param name 调用方法名
|
|
|
|
|
* @param desc 调用方法描述
|
|
|
|
|
*/
|
|
|
|
|
public static void methodOnInvokeThrowTracing(int adviceId, String owner, String name, String desc, int lineNumber) {
|
|
|
|
|
final InvokeTraceable listener = (InvokeTraceable) getListener(adviceId);
|
|
|
|
|
if (null != listener) {
|
|
|
|
|
try {
|
|
|
|
|
listener.invokeThrowTracing(owner, name, desc, lineNumber);
|
|
|
|
|
} catch (Throwable t) {
|
|
|
|
|
logger.warn("advice throw tracing failed.", t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 线程帧栈压栈<br/>
|
|
|
|
|
* 将当前执行帧栈压入线程栈
|
|
|
|
|
*/
|
|
|
|
|
private static void threadFrameStackPush(GaStack<Object> frameStack) {
|
|
|
|
|
GaStack<GaStack<Object>> threadFrameStack = threadBoundContext.get();
|
|
|
|
|
if (null == threadFrameStack) {
|
|
|
|
|
threadBoundContext.set(threadFrameStack = new ThreadUnsafeGaStack<GaStack<Object>>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
threadFrameStack.push(frameStack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static GaStack<Object> threadFrameStackPop() {
|
|
|
|
|
return threadBoundContext.get().pop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static AdviceListener getListener(int adviceId) {
|
|
|
|
|
return advices.get(adviceId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 注册监听器
|
|
|
|
|
*
|
|
|
|
@ -302,45 +112,6 @@ public class AdviceWeaver extends ClassVisitor implements Opcodes {
|
|
|
|
|
return advices.remove(adviceId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void before(AdviceListener listener,
|
|
|
|
|
ClassLoader loader, String className, String methodName, String methodDesc,
|
|
|
|
|
Object target, Object[] args) {
|
|
|
|
|
|
|
|
|
|
if (null != listener) {
|
|
|
|
|
try {
|
|
|
|
|
listener.before(loader, className, methodName, methodDesc, target, args);
|
|
|
|
|
} catch (Throwable t) {
|
|
|
|
|
logger.warn("advice before failed.", t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void afterReturning(AdviceListener listener,
|
|
|
|
|
ClassLoader loader, String className, String methodName, String methodDesc,
|
|
|
|
|
Object target, Object[] args, Object returnObject) {
|
|
|
|
|
if (null != listener) {
|
|
|
|
|
try {
|
|
|
|
|
listener.afterReturning(loader, className, methodName, methodDesc, target, args, returnObject);
|
|
|
|
|
} catch (Throwable t) {
|
|
|
|
|
logger.warn("advice returning failed.", t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void afterThrowing(AdviceListener listener,
|
|
|
|
|
ClassLoader loader, String className, String methodName, String methodDesc,
|
|
|
|
|
Object target, Object[] args, Throwable throwable) {
|
|
|
|
|
if (null != listener) {
|
|
|
|
|
try {
|
|
|
|
|
listener.afterThrowing(loader, className, methodName, methodDesc, target, args, throwable);
|
|
|
|
|
} catch (Throwable t) {
|
|
|
|
|
logger.warn("advice throwing failed.", t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final int adviceId;
|
|
|
|
|
private final boolean isTracing;
|
|
|
|
|
private final boolean skipJDKTrace;
|
|
|
|
|