概述
自己在开发插件的过程中,因为书写拦截器遇到了不少问题,记录于此,以供参考。
拦截普通类
拦截普通类这个场景比较常见,可以net.bytebuddy.matcher.ElementMatchers#named(ClassName)
来进行匹配,具体例子如下:
来自WebfluxWebClient插件org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine
:
@Override
protected ClassMatch enhanceClass() {
return NameMatch.byName(ENHANCE_CLASS);
}
拦截内部类
连接内部实际上和拦截不同类用的方法一样,唯一的不同点是类的写法不同,如果是普通类,直接写其路径名即可,比如
private static final String ENHANCE_CLASS = "com.package.ClassName"
而内部类则需要在内部类和外部类之间加一个#
号来进行分割,而不能用.
具体写法如下:private static final String ENHANCE_CLASS = "com.package.ClassName"
拦截接口实现类
拦截接口实现类则不同,需要通过org.apache.skywalking.apm.agent.core.plugin.match.HierarchyMatch#byHierarchyMatch(String ..paraentType)
传入的参数是可变参数,也就是说传入拦截的接口可以是多个。具体使用方式如下:
来自light4j-plugins
插件的org.apache.skywalking.apm.plugin.light4j.define.LightInstrumentation
:
@Override
protected ClassMatch enhanceClass() {
return HierarchyMatch.byHierarchyMatch(new String[] {ENHANCE_CLASS});
}
拦截注解
拦截注解,则分成两种情况:
拦截注解修饰的类
拦截指定注解修饰的类要通过org.apache.skywalking.apm.agent.core.plugin.match.ClassAnnotationMatch#byClassAnnotationMatch(String .. annotation)
来进行拦截,具体例子如下:
@Override
protected ClassMatch enhanceClass() {
return byClassAnnotationMatch(new String[] {ANNOTATION_NAME});
}
拦截注解修饰的方法
拦截指定注解修饰的类要通过org.apache.skywalking.apm.agent.core.plugin.match.MethodInheritanceAnnotationMatcher#byMethodInheritanceAnnotationMatcher()
,这个方法主要是重写的getInstanceMethodsInterceptPoints()
里边的,具体用法和前边的不同:
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new DeclaredInstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return byMethodInheritanceAnnotationMatcher(named(REQUEST_MAPPING_ENHANCE_ANNOTATION));
}
@Override
public String getMethodsInterceptor() {
return REQUEST_MAPPING_METHOD_INTERCEPTOR;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
同时由于对匹配的类不作要求,因而可以统一写成如下样式:
@Override
protected ClassMatch enhanceClass() {
return ClassAnnotationMatch.byClassAnnotationMatch(getEnhanceAnnotations());
}
总结
本文主要总结了自己写SkyWalking agent端插件的时候常用的匹配方法,并对每一个方法写了一个demo以供参考(所有demo均来自社区插件中的具体类),希望能给想开发SkyWalking插件的小伙伴以帮助。