}
}
第二步:写个ClassFileTransformer,利用Javassist等工具进行字节码修改
public class ClassModifierTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
// 在这里利用Javassist等工具修改类的字节码,返回修改后类的字节数组
return null;
}
}
目前已经有很多文章讲具体使用方法了,大家可以Google下,我这里先介绍两篇:
* [基于Java Instrument的Agent实现](https://gitee.com/vip204888/java-p7)
* [谈谈Java Intrumentation和相关应用](https://gitee.com/vip204888/java-p7)
**原理探究**
========
热替换的核心就在于Instrumentation的两个方法:
void addTransformer(ClassFileTransformer transformer, boolean canRetransform);
void retransformClasses(Class<?>… classes) throws UnmodifiableClassException;
addTransformer()用来注册类的修改器;
retransformClasses()会让类重新加载,从而使得注册的类修改器能够重新修改类的字节码。
下面让我们细细讲讲这两个函数:
**3.1: addTransformer()**
addTransformer的实现在InstrumentationImpl中:
//sun.instrument.InstrumentationImpl
public synchronized void addTransformer(ClassFileTransformer transformer, boolean canRetransform) {
......
mRetransfomableTransformerManager.addTransformer(transformer);
......
}
上面代码省略了一些,可见我们的ClassFileTransformer又被添加到了TransformerManager中,让我们跟进去看看:
//sun.instrument.TransformerManager
public synchronized void addTransformer( ClassFileTransformer transformer) {
TransformerInfo[] oldList = mTransformerList;
TransformerInfo[] newList = new TransformerInfo[oldList.length + 1];
System.arraycopy( oldList,
0,
newList,
0,
oldList.length);
newList[oldList.length] = new TransformerInfo(transformer);
mTransformerList = newList;
}
ClassFileTransformer对象这次被放入了TransformerManager的一个数组中。
OK,注册完毕,很简单对不对?下面我们再来看下稍微复杂点的retransformClasses()吧。
**3.2: retransformClasses()**
这个方法的实现是个Native方