Add comment for InterceptorInstanceLoader

This commit is contained in:
wu.sheng@foxmail.com 2017-10-16 10:49:23 +08:00
parent 2b1829ba81
commit c1b92fd39f
1 changed files with 28 additions and 12 deletions

View File

@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import org.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
@ -58,8 +59,23 @@ public class InterceptorInstanceLoader {
private static Map<ClassLoader, ClassLoader> EXTEND_PLUGIN_CLASSLOADERS = new HashMap<ClassLoader, ClassLoader>();
/**
* Load an instance of interceptor, and keep it singleton.
* Create {@link AgentClassLoader} for each targetClassLoader, as an extend classloader.
* It can load interceptor classes from plugins, activations folders.
*
* @param className
* @param targetClassLoader
* @param <T>
* @return
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws ClassNotFoundException
* @throws AgentPackageNotFoundException
*/
public static <T> T load(String className, ClassLoader targetClassLoader)
throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException, AgentPackageNotFoundException {
throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException, AgentPackageNotFoundException {
if (targetClassLoader == null) {
targetClassLoader = InterceptorInstanceLoader.class.getClassLoader();
}
@ -82,7 +98,7 @@ public class InterceptorInstanceLoader {
}
}
return (T)inst;
return (T) inst;
}
/**
@ -98,7 +114,7 @@ public class InterceptorInstanceLoader {
* @throws ClassNotFoundException
*/
public static <T> T load0(String className, ClassLoader targetClassLoader)
throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException {
throws InvocationTargetException, IllegalAccessException, InstantiationException, ClassNotFoundException {
if (targetClassLoader == null) {
targetClassLoader = InterceptorInstanceLoader.class.getClassLoader();
}
@ -130,14 +146,14 @@ public class InterceptorInstanceLoader {
}
}
return (T)inst;
return (T) inst;
}
/**
* load class from class binary files.
* Most likely all the interceptor implementations should be loaded by this.
*
* @param className interceptor class name.
* @param className interceptor class name.
* @param targetClassLoader the classloader, which should load the interceptor.
* @param <T>
* @return interceptor instance.
@ -146,7 +162,7 @@ public class InterceptorInstanceLoader {
* @throws InstantiationException
*/
private static <T> T loadBinary(String className,
ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException {
ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException {
String path = "/" + className.replace('.', '/').concat(".class");
byte[] data = null;
BufferedInputStream is = null;
@ -186,21 +202,21 @@ public class InterceptorInstanceLoader {
}
defineClassMethod.setAccessible(true);
logger.debug("load binary code of {} to classloader {}", className, targetClassLoader);
Class<?> type = (Class<?>)defineClassMethod.invoke(targetClassLoader, className, data, 0, data.length, null);
return (T)type.newInstance();
Class<?> type = (Class<?>) defineClassMethod.invoke(targetClassLoader, className, data, 0, data.length, null);
return (T) type.newInstance();
}
/**
* Find loaded class in the current classloader.
* Just in case some classes have already been loaded for some reason.
*
* @param className interceptor class name.
* @param className interceptor class name.
* @param targetClassLoader the classloader, which should load the interceptor.
* @param <T>
* @return interceptor instance.
*/
private static <T> T findLoadedClass(String className,
ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException {
ClassLoader targetClassLoader) throws InvocationTargetException, IllegalAccessException, InstantiationException {
Method defineClassMethod = null;
Class<?> targetClassLoaderType = targetClassLoader.getClass();
while (defineClassMethod == null && targetClassLoaderType != null) {
@ -211,10 +227,10 @@ public class InterceptorInstanceLoader {
}
}
defineClassMethod.setAccessible(true);
Class<?> type = (Class<?>)defineClassMethod.invoke(targetClassLoader, className);
Class<?> type = (Class<?>) defineClassMethod.invoke(targetClassLoader, className);
if (type == null) {
return null;
}
return (T)type.newInstance();
return (T) type.newInstance();
}
}