一、前言
关于spring-context包中定义org.springframework.instrument.classloading.LoadTimeWeaver类加载器运行接口、org.springframework.instrument.classloading.weblogic.WebLogicLoadTimeWeaver对于weblogic类加载器实现类,通过该源码示例有足于熟悉了解weblogic加载器入口及自定义weblogic类加载器等。
二、源码示例
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.WebLogicLoadTimeWeaver实现类
package org.springframework.instrument.classloading.weblogic;@b@@b@import java.lang.instrument.ClassFileTransformer;@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 WebLogicLoadTimeWeaver@b@ implements LoadTimeWeaver@b@{@b@ private final WebLogicClassLoaderAdapter classLoader;@b@@b@ public WebLogicLoadTimeWeaver()@b@ {@b@ this(ClassUtils.getDefaultClassLoader());@b@ }@b@@b@ public WebLogicLoadTimeWeaver(ClassLoader classLoader)@b@ {@b@ Assert.notNull(classLoader, "ClassLoader must not be null");@b@ this.classLoader = new WebLogicClassLoaderAdapter(classLoader);@b@ }@b@@b@ public void addTransformer(ClassFileTransformer transformer)@b@ {@b@ this.classLoader.addTransformer(transformer);@b@ }@b@@b@ public ClassLoader getInstrumentableClassLoader()@b@ {@b@ return this.classLoader.getClassLoader();@b@ }@b@@b@ public ClassLoader getThrowawayClassLoader()@b@ {@b@ return @b@ new OverridingClassLoader(this.classLoader.getClassLoader(), this.classLoader@b@ .getThrowawayClassLoader());@b@ }@b@}
package org.springframework.instrument.classloading.weblogic;@b@@b@import java.lang.instrument.ClassFileTransformer;@b@import java.lang.reflect.Constructor;@b@import java.lang.reflect.InvocationHandler;@b@import java.lang.reflect.InvocationTargetException;@b@import java.lang.reflect.Method;@b@import java.lang.reflect.Proxy;@b@import org.springframework.util.Assert;@b@@b@class WebLogicClassLoaderAdapter@b@{@b@ private static final String GENERIC_CLASS_LOADER_NAME = "weblogic.utils.classloaders.GenericClassLoader";@b@ private static final String CLASS_PRE_PROCESSOR_NAME = "weblogic.utils.classloaders.ClassPreProcessor";@b@ private final ClassLoader classLoader;@b@ private final Class<?> wlPreProcessorClass;@b@ private final Method addPreProcessorMethod;@b@ private final Method getClassFinderMethod;@b@ private final Method getParentMethod;@b@ private final Constructor<?> wlGenericClassLoaderConstructor;@b@@b@ public WebLogicClassLoaderAdapter(ClassLoader classLoader)@b@ {@b@ try@b@ {@b@ wlGenericClassLoaderClass = classLoader.loadClass("weblogic.utils.classloaders.GenericClassLoader");@b@ this.wlPreProcessorClass = classLoader.loadClass("weblogic.utils.classloaders.ClassPreProcessor");@b@ this.addPreProcessorMethod = classLoader.getClass().getMethod("addInstanceClassPreProcessor", new Class[] { this.wlPreProcessorClass });@b@@b@ this.getClassFinderMethod = classLoader.getClass().getMethod("getClassFinder", new Class[0]);@b@ this.getParentMethod = classLoader.getClass().getMethod("getParent", new Class[0]);@b@ this.wlGenericClassLoaderConstructor = wlGenericClassLoaderClass.getConstructor(new Class[] { this.getClassFinderMethod@b@ .getReturnType(), ClassLoader.class });@b@ }@b@ catch (Throwable ex) {@b@ throw new IllegalStateException("Could not initialize WebLogic LoadTimeWeaver because WebLogic 10 API classes are not available", ex);@b@ }@b@@b@ if (!(wlGenericClassLoaderClass.isInstance(classLoader)))@b@ {@b@ throw new IllegalArgumentException("ClassLoader must be an instance of [" + wlGenericClassLoaderClass@b@ .getName() + "]: " + classLoader);@b@ }@b@ this.classLoader = classLoader;@b@ }@b@@b@ public void addTransformer(ClassFileTransformer transformer)@b@ {@b@ Assert.notNull(transformer, "ClassFileTransformer must not be null");@b@ try {@b@ InvocationHandler adapter = new WebLogicClassPreProcessorAdapter(transformer, this.classLoader);@b@ Object adapterInstance = Proxy.newProxyInstance(this.wlPreProcessorClass.getClassLoader(), new Class[] { this.wlPreProcessorClass }, adapter);@b@@b@ this.addPreProcessorMethod.invoke(this.classLoader, new Object[] { adapterInstance });@b@ }@b@ catch (InvocationTargetException ex) {@b@ throw new IllegalStateException("WebLogic addInstanceClassPreProcessor method threw exception", ex.getCause());@b@ }@b@ catch (Throwable ex) {@b@ throw new IllegalStateException("Could not invoke WebLogic addInstanceClassPreProcessor method", ex);@b@ }@b@ }@b@@b@ public ClassLoader getClassLoader() {@b@ return this.classLoader; }@b@@b@ public ClassLoader getThrowawayClassLoader() {@b@ Object classFinder;@b@ try {@b@ classFinder = this.getClassFinderMethod.invoke(this.classLoader, new Object[0]);@b@ Object parent = this.getParentMethod.invoke(this.classLoader, new Object[0]);@b@@b@ return ((ClassLoader)this.wlGenericClassLoaderConstructor.newInstance(new Object[] { classFinder, parent }));@b@ }@b@ catch (InvocationTargetException ex) {@b@ throw new IllegalStateException("WebLogic GenericClassLoader constructor failed", ex.getCause());@b@ }@b@ catch (Throwable ex) {@b@ throw new IllegalStateException("Could not construct WebLogic GenericClassLoader", ex);@b@ }@b@ }@b@}
package org.springframework.instrument.classloading.weblogic;@b@@b@import java.lang.instrument.ClassFileTransformer;@b@import java.lang.instrument.IllegalClassFormatException;@b@import java.lang.reflect.InvocationHandler;@b@import java.lang.reflect.Method;@b@import java.util.Hashtable;@b@@b@class WebLogicClassPreProcessorAdapter@b@ implements InvocationHandler@b@{@b@ private final ClassFileTransformer transformer;@b@ private final ClassLoader loader;@b@@b@ public WebLogicClassPreProcessorAdapter(ClassFileTransformer transformer, ClassLoader loader)@b@ {@b@ this.transformer = transformer;@b@ this.loader = loader;@b@ }@b@@b@ public Object invoke(Object proxy, Method method, Object[] args)@b@ throws Throwable@b@ {@b@ String name = method.getName();@b@ if ("equals".equals(name))@b@ return Boolean.valueOf(proxy == args[0]);@b@@b@ if ("hashCode".equals(name))@b@ return Integer.valueOf(super.hashCode());@b@@b@ if ("toString".equals(name))@b@ return toString();@b@@b@ if ("initialize".equals(name)) {@b@ initialize((Hashtable)args[0]);@b@ return null;@b@ }@b@ if ("preProcess".equals(name)) {@b@ return preProcess((String)args[0], (byte[])(byte[])args[1]);@b@ }@b@@b@ throw new IllegalArgumentException("Unknown method: " + method);@b@ }@b@@b@ public void initialize(Hashtable<?, ?> params) {@b@ }@b@@b@ public byte[] preProcess(String className, byte[] classBytes) {@b@ byte[] result;@b@ try {@b@ result = this.transformer.transform(this.loader, className, null, null, classBytes);@b@ return ((result != null) ? result : classBytes);@b@ }@b@ catch (IllegalClassFormatException ex) {@b@ throw new IllegalStateException("Cannot transform due to illegal class format", ex);@b@ }@b@ }@b@@b@ public String toString()@b@ {@b@ return super.getClass().getName() + " for transformer: " + this.transformer;@b@ }@b@}