序
本文主要研究一下skywalking的AbstractClassEnhancePluginDefine
AbstractClassEnhancePluginDefine
skywalking-6.6.0/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java
public abstract class AbstractClassEnhancePluginDefine {
private static final ILog logger = LogManager.getLogger(AbstractClassEnhancePluginDefine.class);
/**
* Main entrance of enhancing the class.
*
* @param typeDescription target class description.
* @param builder byte-buddy's builder to manipulate target class's bytecode.
* @param classLoader load the given transformClass
* @return the new builder, or <code>null</code> if not be enhanced.
* @throws PluginException when set builder failure.
*/
public DynamicType.Builder<?> define(TypeDescription typeDescription,
DynamicType.Builder<?> builder, ClassLoader classLoader, EnhanceContext context) throws PluginException {
String interceptorDefineClassName = this.getClass().getName();
String transformClassName = typeDescription.getTypeName();
if (StringUtil.isEmpty(transformClassName)) {
logger.warn("classname of being intercepted is not defined by {}.", interceptorDefineClassName);
return null;
}
logger.debug("prepare to enhance class {} by {}.", transformClassName, interceptorDefineClassName);
/**
* find witness classes for enhance class
*/
String[] witnessClasses = witnessClasses();
if (witnessClasses != null) {
for (String witnessClass : witnessClasses) {
if (!WitnessClassFinder.INSTANCE.exist(witnessClass, classLoader)) {
logger.warn("enhance class {} by plugin {} is not working. Because witness class {} is not existed.", transformClassName, interceptorDefineClassName,
witnessClass);
return null;
}
}
}
/**
* find origin class source code for interceptor
*/
DynamicType.Builder<?> newClassBuilder = this.enhance(typeDescription, builder, classLoader, context);
context.initializationStageCompleted();
logger.debug("enhance class {} by {} completely.", transformClassName, interceptorDefineClassName);
return newClassBuilder;
}
protected abstract DynamicType.Builder<?> enhance(TypeDescription typeDescription,
DynamicType.Builder<?> newClassBuilder, ClassLoader classLoader, EnhanceContext context) throws PluginException;
/**
* Define the {@link ClassMatch} for filtering class.
*
* @return {@link ClassMatch}
*/
protected abstract ClassMatch enhanceClass();
/**
* Witness classname list. Why need witness classname? Let's see like this: A library existed two released versions
* (like 1.0, 2.0), which include the same target classes, but because of version iterator, they may have the same
* name, but different methods, or different method arguments list. So, if I want to target the particular version
* (let's say 1.0 for example), version number is obvious not an option, this is the moment you need "Witness
* classes". You can add any classes only in this particular release version ( something like class
* com.company.1.x.A, only in 1.0 ), and you can achieve the goal.
*
* @return
*/
protected String[] witnessClasses() {
return new String[] {};
}
public boolean isBootstrapInstrumentation() {
return false;
}
/**
* Constructor methods intercept point. See {@link ConstructorInterceptPoint}
*
* @return collections of {@link ConstructorInterceptPoint}
*/
public abstract ConstructorInterceptPoint[] getConstructorsInterceptPoints();
/**
* Instance methods intercept point. See {@link InstanceMethodsInterceptPoint}
*
* @return collections of {@link InstanceMethodsInterceptPoint}
*/
public abstract InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints();
/**
* Static methods intercept point. See {@link StaticMethodsInterceptPoint}
*
* @return collections of {@link StaticMethodsInterceptPoint}
*/
public abstract StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints();
}
- AbstractClassEnhancePluginDefine提供了define方法,它主要是通过enhance方法创建newClassBuilder,然后执行context.initializationStageCompleted()并返回newClassBuilder;它定义了enhance、enhanceClass、witnessClasses、getConstructorsInterceptPoints、getInstanceMethodsInterceptPoints、getStaticMethodsInterceptPoints抽象方法供子类实现
SkyWalkingAgent.Transformer
skywalking-6.6.0/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java
private static class Transformer implements AgentBuilder.Transformer {
private PluginFinder pluginFinder;
Transformer(PluginFinder pluginFinder) {
this.pluginFinder = pluginFinder;
}
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription,
ClassLoader classLoader, JavaModule module) {
List<AbstractClassEnhancePluginDefine> pluginDefines = pluginFinder.find(typeDescription);
if (pluginDefines.size() > 0) {
DynamicType.Builder<?> newBuilder = builder;
EnhanceContext context = new EnhanceContext();
for (AbstractClassEnhancePluginDefine define : pluginDefines) {
DynamicType.Builder<?> possibleNewBuilder = define.define(typeDescription, newBuilder, classLoader, context);
if (possibleNewBuilder != null) {
newBuilder = possibleNewBuilder;
}
}
if (context.isEnhanced()) {
logger.debug("Finish the prepare stage for {}.", typeDescription.getName());
}
return newBuilder;
}
logger.debug("Matched class {}, but ignore by finding mechanism.", typeDescription.getTypeName());
return builder;
}
}
- SkyWalkingAgent.Transformer会调用AbstractClassEnhancePluginDefine.define方法来创建并返回增强的DynamicType.Builder
小结
AbstractClassEnhancePluginDefine提供了define方法,它主要是通过enhance方法创建newClassBuilder,然后执行context.initializationStageCompleted()并返回newClassBuilder;它定义了enhance、enhanceClass、witnessClasses、getConstructorsInterceptPoints、getInstanceMethodsInterceptPoints、getStaticMethodsInterceptPoints抽象方法供子类实现
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。