源码核心是SkyWalkingAgent
找到一堆插件,来对符合条件的类来代理
通过AbstractClassEnhancePluginDefine.define方法来。
如果有很多版本的插件,spring有2.0版本,3.0版本,4.0版。
具体使用哪个版本,看被增加的类使用的是哪个版本的spring
比如
- spring 2有(A类,B类,C类)
- spring3 有(B类,C类,D类)
- spring4有 (B类,C类,D类)
如果应用程序使用的spring2,那么一定会有A类,那skywalking会选择spring2插件匹配,如果应用程序使用的spring4,由于spring3和spring4的类都相同,那么在比较spring3和spring4中的方法。
找出各种独有的方法来匹配,然后在确定使用哪个版本的插件
以拦截实例方法为例ClassEnhancePluginDefine.enhanceInstance
拦截到的方法,会交给InstMethodsInter来处理。像aop一样。
package com.test;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {
@RequestMapping("/hello")
public Object test(){
return "hello";
}
}
通过arthas 反编译的代码
package com.test;
import com.test.IndexController;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ConstructorInter;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController
implements EnhancedInstance {
private volatile Object _$EnhancedClassField_ws;
public static volatile /* synthetic */ InstMethodsInter delegate$frmhjm0;
public static volatile /* synthetic */ InstMethodsInter delegate$iuour40;
public static volatile /* synthetic */ ConstructorInter delegate$50sob50;
private static final /* synthetic */ Method cachedValue$L2xuREhn$gvchht3;
public static volatile /* synthetic */ InstMethodsInter delegate$acsh691;
public static volatile /* synthetic */ InstMethodsInter delegate$qc4vlq1;
public static volatile /* synthetic */ ConstructorInter delegate$vm2r3i1;
private static final /* synthetic */ Method cachedValue$ImSA9xmx$gvchht3;
public IndexController() {
this(null);
delegate$vm2r3i1.intercept(this, new Object[0]);
}
private /* synthetic */ IndexController(auxiliary.74kq0FAk kq0FAk) {
}
@RequestMapping(value={"/hello"})
public Object test() {
return delegate$qc4vlq1.intercept(this, new Object[0], (Callable<?>)new auxiliary.0hTUYoEs(this), cachedValue$ImSA9xmx$gvchht3);
}
private /* synthetic */ Object test$original$bo9sTfYx() {
/*15*/ return "hello";
}
static {
ClassLoader.getSystemClassLoader().loadClass("org.apache.skywalking.apm.dependencies.net.bytebuddy.dynamic.Nexus").getMethod("initialize", Class.class, Integer.TYPE).invoke(null, IndexController.class, 1905055592);
cachedValue$ImSA9xmx$gvchht3 = IndexController.class.getMethod("test", new Class[0]);
}
final /* synthetic */ Object test$original$bo9sTfYx$accessor$ImSA9xmx() {
return this.test$original$bo9sTfYx();
}
}
有上面的源码可以看出,对test方法进行了增强,内部其实是调用了delegate$qc4vlq1的intercept方法,就是InstMethodsInter中aop相关逻辑
会执行InstanceMethodsAroundInterceptor接口的3个方法。
以duboo插件为类DubboInterceptor的拦截器实现了InstanceMethodsAroundInterceptor