赞
踩
instrumentation.redefineClasses 可以重新定义类文件
import java.lang.instrument.*; import java.lang.reflect.Method; import java.security.ProtectionDomain; import java.util.*; public class TestTransformer implements ClassFileTransformer, Runnable { private static Map<String, List<TransformerLoad>> enhanceModels = new HashMap<>(); private static List<String> list = new ArrayList(); private Instrumentation instrumentation = null; static { //后面可以改成spi扩展的方式 list.add("org/apache/logging/log4j/core/layout/PatternLayout$Builder"); list.add("ch/qos/logback/core/pattern/PatternLayoutBase"); list.add("ch/qos/logback/classic/PatternLayout"); list.add("sun/net/www/http/HttpClient"); } public TestTransformer(Instrumentation instrumentation) { this.instrumentation = instrumentation; } @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (list.contains(className)) { try{ List<TransformerLoad> transformerLoadList = null; String key = "-"; if (loader != null){ key = loader.toString(); } if (! enhanceModels.containsKey(key)){ transformerLoadList = new ArrayList<>(); enhanceModels.put(key, transformerLoadList); }else { transformerLoadList = enhanceModels.get(key); } TransformerLoad transformerLoad = new TransformerLoad(); transformerLoad.setClassLoader(loader); transformerLoad.setClassBeingRedefined(classBeingRedefined); transformerLoad.setClassfileBuffer(classfileBuffer); transformerLoad.setClassName(className); transformerLoad.setProtectionDomain(protectionDomain); transformerLoadList.add(transformerLoad); } catch (Throwable e){ e.printStackTrace(); } } return classfileBuffer; } public void start() { Thread thread = new Thread(this::run); thread.setName("tTransformer thread"); thread.setDaemon(true); thread.start(); } @Override public void run() { try { Thread.sleep(40000); } catch (InterruptedException e) { e.printStackTrace(); } List<TransformerLoad> initiatedTransformerLoadList = new ArrayList<>(); System.out.println("---------------redefineClasses start:"); enhanceModels.forEach((k, v) -> { List<TransformerLoad> list = v; if (list != null) { // ClassLoader classLoader = list.get(0).getClassLoader(); // Class[] initiatedClasses = instrumentation.getInitiatedClasses(classLoader); for (TransformerLoad transformerLoad : list) { initiatedTransformerLoadList.add(transformerLoad); // for (Class cla : initiatedClasses) { // //加载过的class // if (cla.getName().equals(transformerLoad.getClassName())) { // initiatedTransformerLoadList.add(transformerLoad); // } // } } } }); for (TransformerLoad transformerLoad : initiatedTransformerLoadList){ ClassLoader loader = transformerLoad.getClassLoader(); if (loader == null){ loader = Thread.currentThread().getContextClassLoader(); } try { String className = transformerLoad.className.replaceAll("/","."); Class cla = loader.loadClass(className); ClassDefinition classDefinition = new ClassDefinition(cla,transformerLoad.classfileBuffer); if (instrumentation.isRedefineClassesSupported() && instrumentation.isModifiableClass(cla)){ try { instrumentation.redefineClasses(classDefinition); System.out.println("---------------redefineClasses class:"+transformerLoad.className); } catch (UnmodifiableClassException e) { e.printStackTrace(); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } /** * 转换加载模型 */ public static class TransformerLoad { private ClassLoader classLoader; private String className; private byte[] classfileBuffer; private Class<?> classBeingRedefined; private ProtectionDomain protectionDomain; public ClassLoader getClassLoader() { return classLoader; } public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public byte[] getClassfileBuffer() { return classfileBuffer; } public void setClassfileBuffer(byte[] classfileBuffer) { this.classfileBuffer = classfileBuffer; } public Class<?> getClassBeingRedefined() { return classBeingRedefined; } public void setClassBeingRedefined(Class<?> classBeingRedefined) { this.classBeingRedefined = classBeingRedefined; } public ProtectionDomain getProtectionDomain() { return protectionDomain; } public void setProtectionDomain(ProtectionDomain protectionDomain) { this.protectionDomain = protectionDomain; } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。