希望各位拍砖:
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);
}
}
}