希望各位拍砖:
package com.huawei.c3.proxypattern; public interface IPerson { void say(); void eat(); void sleep(); }
package com.huawei.c3.proxypattern; public class Teacher implements IPerson { @Override public void say() { System.out.println("teacher is saying"); } @Override public void eat() { System.out.println("teacher is eatting"); } @Override public void sleep() { System.out.println("teacher is sleeping"); } }
package com.huawei.c3.proxypattern; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target) { this.target = target; } public void before() { System.out.println("before invoke"); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; before(); if ("equals".equals(method.getName())) { result = (proxy == args[0]); } if ("hashCode".equals(method.getName())) { result = new Integer(System.identityHashCode(proxy)); } if ("toString".equals(method.getName())) { Integer hashcode=new Integer(System.identityHashCode(proxy)); result = proxy.getClass().getName() + "@" +hashcode ; } else { result = method.invoke(target, args); } after(); return result; } private void after() { System.out.println("after invoke"); } }
package com.huawei.c3.proxypattern; import java.lang.reflect.Proxy; public class ProxyTest { public static void main(String[] args) { String fullName="com.huawei.c3.Teacher"; Class<?> clazz; try { clazz = Class.forName(fullName); ClassLoader currentLoader=clazz.getClassLoader(); Object instance=clazz.newInstance(); Object proxyInstance=Proxy.newProxyInstance(currentLoader, new Class[]{IPerson.class}, new MyInvocationHandler(instance)); IPerson person=null; if(proxyInstance instanceof IPerson){ person=(IPerson)proxyInstance; //person.say(); // System.out.println(proxyInstance==proxyInstance); // System.out.println(proxyInstance.toString()); // System.out.println(proxyInstance.hashCode()); //System.out.println(proxyInstance.equals(proxyInstance)); System.out.println(proxyInstance.hashCode()); //System.out.println(proxyInstance.toString()); System.out.println(instance.hashCode()); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
现在存在的疑问是,我在invoke方法里面进行对hashCode,toString,equals方法进行了拦截。避免造成自己不等于自己的问题。但是调用System.identityCode(proxy)方法得到的哈希码为什么和被代理对象的哈希码相同呢?(这是值得思考的一个问题)
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 Manager {
private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals",
new Class[] { Class.forName("java.lang.Object") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode",
new Class[0]);
m3 = Class.forName("com.ml.test.Manager").getMethod("test",
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());
}
}
public $Proxy0(InvocationHandler invocationhandler) {
super(invocationhandler);
}
@Override
public final boolean equals(Object obj) {
try {
return ((Boolean) super.h.invoke(this, m1, new Object[] { obj }))
.booleanValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final int hashCode() {
try {
return ((Integer) super.h.invoke(this, m0, null)).intValue();
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final void test() {
try {
super.h.invoke(this, m3, null);
return;
} catch (Error e) {
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
@Override
public final String toString() {
try {
return (String) super.h.invoke(this, m2, null);
} catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
}