引自:http://yy629.iteye.com/blog/681430
动态代理,可以对接口、类进行代理,其中jdk自带的动态代理,只能通过接口代理,其他如:asm、cglib、javaassist对两者均可代理,其中保存jdk动态类方法:
package demo;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Properties;
/**
* @author yeyong
*/
public class ProxyTest2 {
public static void main(String[] args) throws Exception {
// 添加以下的几段代码, 就可以将代理生成的字节码保存起来了
Field field = System.class.getDeclaredField("props");
field.setAccessible(true);
Properties props = (Properties) field.get(null);
props.put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
Package pkg = ProxyTest2.class.getPackage();
if (pkg != null) {
String packagePath = pkg.getName().replace(".", File.pathSeparator);
new File(packagePath).mkdirs();
}
IA a = new IAImpl();
InvocationHandlerImpl ih = new InvocationHandlerImpl(a);
IA proxyA = (IA) Proxy.newProxyInstance(a.getClass().getClassLoader(),
a.getClass().getInterfaces(), ih);
proxyA.a();
}
}
interface IA {
void a();
int b(String str);
}
class IAImpl implements IA {
@Override
public void a() {
System.out.println("IAImpl.a()");
}
@Override
public int b(String str) {
System.out.println("IAImpl.b()");
return 0;
}
}
class InvocationHandlerImpl implements InvocationHandler {
private Object target;
public InvocationHandlerImpl(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before...");
Object res = method.invoke(target, args);
System.out.println("after...");
return res;
}
}
反编译后源码如下
package demo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements IA {
private static Method m1;
private static Method m4;
private static Method m3;
private static Method m0;
private static Method m2;
public $Proxy0(InvocationHandler paramInvocationHandler) {
super(paramInvocationHandler);
}
public final boolean equals(Object paramObject) {
try {
return ((Boolean) this.h.invoke(this, m1,
new Object[] { paramObject })).booleanValue();
} catch (RuntimeException localRuntimeException) {
throw localRuntimeException;
} catch (Throwable localThrowable) {
throw new UndeclaredThrowableException(localThrowable);
}
}
public final int b(String paramString) {
try {
return ((Integer) this.h.invoke(this, m4,
new Object[] { paramString })).intValue();
} catch (RuntimeException localRuntimeException) {
throw localRuntimeException;
} catch (Throwable localThrowable) {
throw new UndeclaredThrowableException(localThrowable);
}
}
public final void a() {
try {
this.h.invoke(this, m3, null);
return;
} catch (RuntimeException localRuntimeException) {
throw localRuntimeException;
} catch (Throwable localThrowable) {
throw new UndeclaredThrowableException(localThrowable);
}
}
public final int hashCode() {
try {
return ((Integer) this.h.invoke(this, m0, null)).intValue();
} catch (RuntimeException localRuntimeException) {
throw localRuntimeException;
} catch (Throwable localThrowable) {
throw new UndeclaredThrowableException(localThrowable);
}
}
public final String toString() {
try {
return (String) this.h.invoke(this, m2, null);
} catch (RuntimeException localRuntimeException) {
throw localRuntimeException;
} catch (Throwable localThrowable) {
throw new UndeclaredThrowableException(localThrowable);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals",
new Class[] { Class.forName("java.lang.Object") });
m4 = Class.forName("demo.IA").getMethod("b",
new Class[] { Class.forName("java.lang.String") });
m3 = Class.forName("demo.IA").getMethod("a", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
} catch (NoSuchMethodException localNoSuchMethodException) {
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
} catch (ClassNotFoundException localClassNotFoundException) {
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
}