序
本文主要研究一下skywalking的async-annotation-plugin
AsyncExecutionInterceptorInstrumentation
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/define/AsyncExecutionInterceptorInstrumentation.java
public class AsyncExecutionInterceptorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[]{
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher getMethodsMatcher() {
return named("doSubmit").and(takesArgumentWithType(0, "java.util.concurrent.Callable"));
}
@Override
public String getMethodsInterceptor() {
return "org.apache.skywalking.apm.plugin.spring.async.DoSubmitMethodInterceptor";
}
@Override
public boolean isOverrideArgs() {
return true;
}
}
};
}
@Override
public ClassMatch enhanceClass() {
return byName("org.springframework.aop.interceptor.AsyncExecutionAspectSupport");
}
}
- AsyncExecutionInterceptorInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,它使用org.apache.skywalking.apm.plugin.spring.async.DoSubmitMethodInterceptor拦截org.springframework.aop.interceptor.AsyncExecutionAspectSupport的第一个参数类型为java.util.concurrent.Callable的doSubmit方法
DoSubmitMethodInterceptor
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/DoSubmitMethodInterceptor.java
public class DoSubmitMethodInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
if (ContextManager.isActive()) {
allArguments[0] = new SWCallable((Callable) allArguments[0], ContextManager.capture());
}
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class>[] argumentsTypes, Object ret) throws Throwable {
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class>[] argumentsTypes, Throwable t) {
}
}
- DoSubmitMethodInterceptor实现了InstanceMethodsAroundInterceptor接口,其beforeMethod方法将allArguments[0]包装为SWCallable
SWCallable
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/SWCallable.java
public class SWCallable implements Callable {
private static final String OPERATION_NAME = "SpringAsync";
private Callable callable;
private ContextSnapshot snapshot;
SWCallable(Callable callable, ContextSnapshot snapshot) {
this.callable = callable;
this.snapshot = snapshot;
}
@Override
public V call() throws Exception {
AbstractSpan span = ContextManager.createLocalSpan(SWCallable.OPERATION_NAME);
span.setComponent(ComponentsDefine.SPRING_ASYNC);
try {
ContextManager.continued(snapshot);
return callable.call();
} catch (Exception e) {
ContextManager.activeSpan().errorOccurred().log(e);
throw e;
} finally {
ContextManager.stopSpan();
}
}
}
- SWCallable实现了Callable接口,其call方法在执行callable.call()之前先ContextManager.createLocalSpan,然后执行ContextManager.continued(snapshot),之后在catch异常里头执行ContextManager.activeSpan().errorOccurred().log(e),最后在finally里头执行ContextManager.stopSpan()
小结
AsyncExecutionInterceptorInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,它使用org.apache.skywalking.apm.plugin.spring.async.DoSubmitMethodInterceptor拦截org.springframework.aop.interceptor.AsyncExecutionAspectSupport的第一个参数类型为java.util.concurrent.Callable的doSubmit方法
doc
- AsyncExecutionInterceptorInstrumentation