首页

关于spring-context包中获取websphere类加载器WebSphereLoadTimeWeaver对象源码示例说明

标签:spring-context,websphere,类加载器,WebSphereLoadTimeWeaver     发布时间:2018-08-31   

一、前言

关于spring-context包中定义org.springframework.instrument.classloading.LoadTimeWeaver类加载器运行接口、org.springframework.instrument.classloading.websphere.WebSphereLoadTimeWeaver对于websphere类加载器实现类,通过该源码示例有足于熟悉了解websphere加载器入口及自定义websphere类加载器等。

二、源码示例

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.WebSphereLoadTimeWeaver实现类

package org.springframework.instrument.classloading.websphere;@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 WebSphereLoadTimeWeaver@b@  implements LoadTimeWeaver@b@{@b@  private final WebSphereClassLoaderAdapter classLoader;@b@@b@  public WebSphereLoadTimeWeaver()@b@  {@b@    this(ClassUtils.getDefaultClassLoader());@b@  }@b@@b@  public WebSphereLoadTimeWeaver(ClassLoader classLoader)@b@  {@b@    Assert.notNull(classLoader, "ClassLoader must not be null");@b@    this.classLoader = new WebSphereClassLoaderAdapter(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.websphere;@b@@b@import java.lang.instrument.ClassFileTransformer;@b@import java.lang.reflect.Constructor;@b@import java.lang.reflect.Field;@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 java.util.List;@b@import org.springframework.util.Assert;@b@@b@class WebSphereClassLoaderAdapter@b@{@b@  private static final String COMPOUND_CLASS_LOADER_NAME = "com.ibm.ws.classloader.CompoundClassLoader";@b@  private static final String CLASS_PRE_PROCESSOR_NAME = "com.ibm.websphere.classloader.ClassLoaderInstancePreDefinePlugin";@b@  private static final String PLUGINS_FIELD = "preDefinePlugins";@b@  private ClassLoader classLoader;@b@  private Class<?> wsPreProcessorClass;@b@  private Method addPreDefinePlugin;@b@  private Constructor<? extends ClassLoader> cloneConstructor;@b@  private Field transformerList;@b@@b@  public WebSphereClassLoaderAdapter(ClassLoader classLoader)@b@  {@b@    try@b@    {@b@      wsCompoundClassLoaderClass = classLoader.loadClass("com.ibm.ws.classloader.CompoundClassLoader");@b@      this.cloneConstructor = classLoader.getClass().getDeclaredConstructor(new Class[] { wsCompoundClassLoaderClass });@b@      this.cloneConstructor.setAccessible(true);@b@@b@      this.wsPreProcessorClass = classLoader.loadClass("com.ibm.websphere.classloader.ClassLoaderInstancePreDefinePlugin");@b@      this.addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", new Class[] { this.wsPreProcessorClass });@b@      this.transformerList = wsCompoundClassLoaderClass.getDeclaredField("preDefinePlugins");@b@      this.transformerList.setAccessible(true);@b@    }@b@    catch (Throwable ex) {@b@      throw new IllegalStateException("Could not initialize WebSphere LoadTimeWeaver because WebSphere API classes are not available", ex);@b@    }@b@@b@    if (!(wsCompoundClassLoaderClass.isInstance(classLoader)))@b@      throw new IllegalArgumentException("ClassLoader must be instance of com.ibm.ws.classloader.CompoundClassLoader");@b@@b@    this.classLoader = classLoader;@b@  }@b@@b@  public ClassLoader getClassLoader()@b@  {@b@    return this.classLoader;@b@  }@b@@b@  public void addTransformer(ClassFileTransformer transformer) {@b@    Assert.notNull(transformer, "ClassFileTransformer must not be null");@b@    try {@b@      InvocationHandler adapter = new WebSphereClassPreDefinePlugin(transformer);@b@      Object adapterInstance = Proxy.newProxyInstance(this.wsPreProcessorClass.getClassLoader(), new Class[] { this.wsPreProcessorClass }, adapter);@b@@b@      this.addPreDefinePlugin.invoke(this.classLoader, new Object[] { adapterInstance });@b@    }@b@    catch (InvocationTargetException ex) {@b@      throw new IllegalStateException("WebSphere addPreDefinePlugin method threw exception", ex.getCause());@b@    }@b@    catch (Throwable ex) {@b@      throw new IllegalStateException("Could not invoke WebSphere addPreDefinePlugin method", ex);@b@    }@b@  }@b@@b@  public ClassLoader getThrowawayClassLoader() {@b@    try {@b@      ClassLoader loader = (ClassLoader)this.cloneConstructor.newInstance(new Object[] { getClassLoader() });@b@@b@      List list = (List)this.transformerList.get(loader);@b@      list.clear();@b@      return loader;@b@    }@b@    catch (InvocationTargetException ex) {@b@      throw new IllegalStateException("WebSphere CompoundClassLoader constructor failed", ex.getCause());@b@    }@b@    catch (Throwable ex) {@b@      throw new IllegalStateException("Could not construct WebSphere CompoundClassLoader", ex);@b@    }@b@  }@b@}
package org.springframework.instrument.classloading.websphere;@b@@b@import java.lang.instrument.ClassFileTransformer;@b@import java.lang.reflect.InvocationHandler;@b@import java.lang.reflect.Method;@b@import java.security.CodeSource;@b@import org.springframework.util.FileCopyUtils;@b@@b@class WebSphereClassPreDefinePlugin@b@  implements InvocationHandler@b@{@b@  private final ClassFileTransformer transformer;@b@@b@  public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer)@b@  {@b@    this.transformer = transformer;@b@    ClassLoader classLoader = transformer.getClass().getClassLoader();@b@    try@b@    {@b@      String dummyClass = Dummy.class.getName().replace('.', '/');@b@      byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class"));@b@      transformer.transform(classLoader, dummyClass, null, null, bytes);@b@    }@b@    catch (Throwable ex) {@b@      throw new IllegalArgumentException("Cannot load transformer", ex);@b@    }@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 ("transformClass".equals(name)) {@b@      return transform((String)args[0], (byte[])(byte[])args[1], (CodeSource)args[2], (ClassLoader)args[3]);@b@    }@b@@b@    throw new IllegalArgumentException("Unknown method: " + method);@b@  }@b@@b@  protected byte[] transform(String className, byte[] classfileBuffer, CodeSource codeSource, ClassLoader classLoader)@b@    throws Exception@b@  {@b@    byte[] result = this.transformer.transform(classLoader, className.replace('.', '/'), null, null, classfileBuffer);@b@    return ((result != null) ? result : classfileBuffer);@b@  }@b@@b@  public String toString()@b@  {@b@    return super.getClass().getName() + " for transformer: " + this.transformer;@b@  }@b@@b@  private static class Dummy@b@  {@b@  }@b@}