java代理模式(动态代理的实现)

希望各位拍砖: 

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);
   }
}
}

猜你喜欢

转载自sunzhangming-163-com.iteye.com/blog/2034101