先说结论:
1,动态代理,继承Proxy,类实现接口。但需要反射。动态代理类,会被缓存。但反射仍慢。
2,100M次性能结果:
testDynamicProxyPerformance=73277 //先newInstance(),再方法的反射调用。
testDynamicProxyFilePerformance=1639 //没有newInstance(),只有方法的反射调用。
testStaticProxyPerformance=38
过程:
1,接口。
package time.river.proxy;
public interface ITarget{
public void doA(int age);
public void doB(String name, int age);
public int getAge();
public void setAge(int age);
}
2,目标类
package time.river.proxy;
public class MyTarget implements ITarget {
private int age;
@Override
public void doA(int age) {
System.out.println("doA.....,age=" + age);
}
@Override
public void doB(String name, int age) {
System.out.println("doB.....,name=" + name + ",age=" + age);
}
@Override
public int getAge() {
return age;
}
@Override
public void setAge(int age) {
this.age = age;
}
}
3,Handler
package time.river.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyHandler implements InvocationHandler {
private Object targetObj;
public MyHandler(Object targetObj) {
this.targetObj = targetObj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// System.out.println("哥是代理------------------------------------");
return method.invoke(targetObj, args);
}
}
4, 测试类
package time.river.proxy;
import java.io.FileOutputStream;
import java.lang.reflect.Proxy;
import sun.misc.ProxyGenerator;
public class Test {
public static void main(String args[]) throws Exception{
// testDynamicProxy();
// createProxyClassFile();
// testProxyFile();
testDynamicProxyPerformance();
testDynamicProxyFilePerformance();
testStaticProxyPerformance();
}
private static void testDynamicProxy() throws Exception{
MyTarget target = new MyTarget();
ITarget proxy = (ITarget) Proxy.newProxyInstance(ITarget.class.getClassLoader(),
new Class[] { ITarget.class }, new MyHandler(target));
// proxy.doA(20);
// proxy.doB("wnj", 20);
proxy.setAge(20);
}
/**
* 生成的动态代理文件。使用jad反编译。
*/
private static void createProxyClassFile() throws Exception{
String name = "DynamicProxy"; //生成的动态代理文件。
//Proxy内部方法:ProxyGenerator.generateProxyClass。
byte[] data = ProxyGenerator.generateProxyClass(name, new Class[] { ITarget.class });
FileOutputStream out = new FileOutputStream(name + ".class");
out.write(data);
out.close();
}
public static void testProxyFile(){
MyTarget target = new MyTarget();
MyHandler handler = new MyHandler(target);
DynamicProxy proxy = new DynamicProxy(handler);
// proxy.doA(20);
// proxy.doB("wnj", 20);
proxy.setAge(20);
}
private static int cnt = 1000 * 1000 * 100;
private static void testDynamicProxyPerformance() throws Exception{
long s = System.currentTimeMillis();
for (int i = 0; i < cnt; i++) {
testDynamicProxy();
}
long e = System.currentTimeMillis();
System.out.println("testDynamicProxyPerformance="+(e-s));
}
private static void testDynamicProxyFilePerformance() throws Exception{
long s = System.currentTimeMillis();
for (int i = 0; i < cnt; i++) {
testProxyFile();
}
long e = System.currentTimeMillis();
System.out.println("testDynamicProxyFilePerformance="+(e-s));
}
private static void testStaticProxyPerformance() throws Exception{
long s = System.currentTimeMillis();
for (int i = 0; i < cnt; i++) {
testStaticProxy();
}
long e = System.currentTimeMillis();
System.out.println("testStaticProxyPerformance="+(e-s));
}
public static void testStaticProxy(){
MyTarget target = new MyTarget();
StaticProxy proxy = new StaticProxy(target);
// proxy.doA(20);
// proxy.doB("wnj", 20);
proxy.setAge(20);
}
}
5,动态代理类。保存到class文件,再用jad反编译。
package time.river.proxy;
import java.lang.reflect.*;
import time.river.proxy.ITarget;
/**
* Test类createProxyClassFile()方法,生成的class文件。然后用jad反编译,再修改语法错误。
*/
public final class DynamicProxy extends Proxy implements ITarget {
public DynamicProxy(InvocationHandler invocationhandler) {
super(invocationhandler);
}
public final void setAge(int i) {
try {
super.h.invoke(this, m6, new Object[] { Integer.valueOf(i) });
return;
} catch (Error _ex) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final boolean equals(Object obj) {
try {
return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })).booleanValue();
} catch (Error _ex) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
return false;
}
public final void doA(int i) {
try {
super.h.invoke(this, m3, new Object[] { Integer.valueOf(i) });
return;
} catch (Error _ex) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final int getAge() {
try {
return ((Integer) super.h.invoke(this, m5, null)).intValue();
} catch (Error _ex) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
return 0;
}
public final void doB(String s, int i) {
try {
super.h.invoke(this, m4, new Object[] { s, Integer.valueOf(i) });
return;
} catch (Error _ex) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final int hashCode() {
try {
return ((Integer) super.h.invoke(this, m0, null)).intValue();
} catch (Error _ex) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
return 0;
}
public final String toString() {
try {
return (String) super.h.invoke(this, m2, null);
} catch (Error _ex) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
return "";
}
private static Method m6;
private static Method m1;
private static Method m3;
private static Method m5;
private static Method m4;
private static Method m0;
private static Method m2;
static {
try {
m6 = Class.forName("time.river.proxy.ITarget").getMethod("setAge", new Class[] { Integer.TYPE });
m1 = Class.forName("java.lang.Object").getMethod("equals",
new Class[] { Class.forName("java.lang.Object") });
m3 = Class.forName("time.river.proxy.ITarget").getMethod("doA", new Class[] { Integer.TYPE });
m5 = Class.forName("time.river.proxy.ITarget").getMethod("getAge", new Class[0]);
m4 = Class.forName("time.river.proxy.ITarget").getMethod("doB",
new Class[] { Class.forName("java.lang.String"), Integer.TYPE });
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
} catch (NoSuchMethodException nosuchmethodexception) {
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
} catch (ClassNotFoundException classnotfoundexception) {
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
}
6,静态代理类
package time.river.proxy;
public class StaticProxy implements ITarget{
private ITarget target;
public StaticProxy(ITarget target) {
super();
this.target = target;
}
@Override
public void doA(int age) {
}
@Override
public void doB(String name, int age) {
}
@Override
public int getAge() {
return 0;
}
@Override
public void setAge(int age) {
target.setAge(age);
}
}