一、前言
关于spring-context包中定义org.springframework.instrument.classloading.LoadTimeWeaver类加载器运行接口、org.springframework.instrument.classloading.tomcat.TomcatLoadTimeWeaver对于tomcat类加载器实现类,通过该源码示例有足于熟悉了解tomcat加载器入口及自定义tomcat类加载器等。
二、源码示例
1.LoadTimeWeaver接口
package org.springframework.instrument.classloading;@b@@b@import java.lang.instrument.ClassFileTransformer;@b@@b@public abstract interface LoadTimeWeaver@b@{@b@ public abstract void addTransformer(ClassFileTransformer paramClassFileTransformer);@b@@b@ public abstract ClassLoader getInstrumentableClassLoader();@b@@b@ public abstract ClassLoader getThrowawayClassLoader();@b@}
2.TomcatLoadTimeWeaver实现类
package org.springframework.instrument.classloading.tomcat;@b@@b@import java.lang.instrument.ClassFileTransformer;@b@import java.lang.reflect.InvocationTargetException;@b@import java.lang.reflect.Method;@b@import org.springframework.core.OverridingClassLoader;@b@import org.springframework.instrument.classloading.LoadTimeWeaver;@b@import org.springframework.util.Assert;@b@import org.springframework.util.ClassUtils;@b@@b@public class TomcatLoadTimeWeaver@b@ implements LoadTimeWeaver@b@{@b@ private static final String INSTRUMENTABLE_LOADER_CLASS_NAME = "org.apache.tomcat.InstrumentableClassLoader";@b@ private final ClassLoader classLoader;@b@ private final Method addTransformerMethod;@b@ private final Method copyMethod;@b@@b@ public TomcatLoadTimeWeaver()@b@ {@b@ this(ClassUtils.getDefaultClassLoader());@b@ }@b@@b@ public TomcatLoadTimeWeaver(ClassLoader classLoader) {@b@ Assert.notNull(classLoader, "ClassLoader must not be null");@b@ this.classLoader = classLoader;@b@ try@b@ {@b@ instrumentableLoaderClass = classLoader.loadClass("org.apache.tomcat.InstrumentableClassLoader");@b@ if (!(instrumentableLoaderClass.isInstance(classLoader)))@b@ {@b@ instrumentableLoaderClass = classLoader.getClass();@b@ }@b@ }@b@ catch (ClassNotFoundException ex)@b@ {@b@ instrumentableLoaderClass = classLoader.getClass();@b@ }@b@ try@b@ {@b@ this.addTransformerMethod = instrumentableLoaderClass.getMethod("addTransformer", new Class[] { ClassFileTransformer.class });@b@@b@ Method copyMethod = ClassUtils.getMethodIfAvailable(instrumentableLoaderClass, "copyWithoutTransformers", new Class[0]);@b@ if (copyMethod == null)@b@ {@b@ copyMethod = instrumentableLoaderClass.getMethod("getThrowawayClassLoader", new Class[0]);@b@ }@b@ this.copyMethod = copyMethod;@b@ }@b@ catch (Throwable ex) {@b@ throw new IllegalStateException("Could not initialize TomcatLoadTimeWeaver because Tomcat API classes are not available", ex);@b@ }@b@ }@b@@b@ public void addTransformer(ClassFileTransformer transformer)@b@ {@b@ try@b@ {@b@ this.addTransformerMethod.invoke(this.classLoader, new Object[] { transformer });@b@ }@b@ catch (InvocationTargetException ex) {@b@ throw new IllegalStateException("Tomcat addTransformer method threw exception", ex.getCause());@b@ }@b@ catch (Throwable ex) {@b@ throw new IllegalStateException("Could not invoke Tomcat addTransformer method", ex);@b@ }@b@ }@b@@b@ public ClassLoader getInstrumentableClassLoader()@b@ {@b@ return this.classLoader;@b@ }@b@@b@ public ClassLoader getThrowawayClassLoader()@b@ {@b@ try {@b@ return new OverridingClassLoader(this.classLoader, (ClassLoader)this.copyMethod.invoke(this.classLoader, new Object[0]));@b@ }@b@ catch (InvocationTargetException ex) {@b@ throw new IllegalStateException("Tomcat copy method threw exception", ex.getCause());@b@ }@b@ catch (Throwable ex) {@b@ throw new IllegalStateException("Could not invoke Tomcat copy method", ex);@b@ }@b@ }@b@}