Java的两种instrument方法
Java的两种instrument方法
1. 通过proxy
假设我们想在Account类中的operation中加入某个安全检查机制check。
public class Account {
public void operation() {
// todo
}
}
public class Check {
public static void check() {
// todo
}
}
这个时候我们需要先定义一个 Account类的接口:
public interface Account {
void operation();
}
然后把令Account类定义为一个实现类:
public class AccountImpl extends Account{
public void operation() {
// todo
}
}
然后定义一个 Account类的 Decorator
public class AccountCheck implements Account {
private Account account;
public AccountCheck (Account account) {
this.account = account;
}
public void operation() {
Checker.check();
account.operation();
}
}
2. 通过InvocationHandler
在把Account定义为接口之后,在AccountImpl中实现接口,然后写一个InnovationHandler子类中实现invoke方法,在Account的方法调用时候对方法进行instrument
class CheckerInvocationHandler implements InvocationHandler {
private Object proxyedObject;
public CheckerInvocationHandler(Object o) {
proxyedObject = o;
}
public Object invoke(Object object, Method method, Object[] arguments)
throws Throwable {
if (object instanceof Account && method.getName().equals("opertaion")) {
Checker.check();
}
return method.invoke(proxyedObject, arguments);
}
}
public static void main(String[] args) {
Account account = (Account) Proxy.newProxyInstance(
Account.class.getClassLoader(),
new Class[] { Account.class },
new CheckerInvocationHandler(new AccountImpl())
);
account.function();
}
Spring中用到了很多这个机制。
Java byte array to inputsteam
Map<String, byte[]> classMap = ClazzReader.readClazz(classPath, resourceName);
for (Map.Entry<String, byte[]> entry : classMap.entrySet()) {
String className1 = entry.getKey();
//System.out.println("className1: " + className1);
InputStream is = ByteSource.wrap(entry.getValue()).openStream();
System.out.println("|-- " + className1);
ClassReader reader = new ClassReader(is);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassVisitor pubMethAdapter = new PublicizeMethodAdapter(ASM4, writer);
reader.accept(pubMethAdapter, ClassReader.SKIP_DEBUG);
}