聊聊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抽象方法供子类实现

doc

  • AbstractClassEnhancePluginDefine

以上是 聊聊skywalking的AbstractClassEnhancePluginDefine 的全部内容, 来源链接: utcz.com/z/514099.html

回到顶部