java中动态代理代码解析

2020-05-30  本文已影响0人  ModestStorm
接口类IPerson
public interface IPerson {
    void setSex(int sex) throws Throwable;
    int getSex() throws Throwable;
}
具体实现类Man
public class Man implements IPerson {

    private int sex;

    @Override
    public void setSex(int sex) {
        this.sex = sex;
    }

    @Override
    public int getSex() {
        return sex;
    }

    @NonNull
    @Override
    public String toString() {
        return "hello";
    }
}
动态代理类生成
 @Test
    public void testDynamic() throws Throwable {
        Man man=new Man();
        man.setSex(10);
        IPerson proxyPerson= (IPerson) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class[]{IPerson.class},new CustomInvocationHandler(man));
//        proxyPerson.setSex(12);
        System.out.print("man sex=" + proxyPerson.getSex());
    }

    private class CustomInvocationHandler implements InvocationHandler {
        IPerson target;
       public CustomInvocationHandler(IPerson target){
            this.target=target;
        }

        /*
         * 参数proxy:动态代理对象$proxy0的实例,不是man的示例,网上有些博客写错了
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println(">>>> before:"+method.getName());
            if(args!=null){
                for (Object arg : args) {
                    System.out.println("args:"+arg);
                }
            }
            Object result=method.invoke(target,args);
            //动态修改原值
            if(result instanceof Integer){
                result=((Integer) result).intValue()+1;
            }
            System.out.println(">>> end success");
            return result;
        }
    }
}

反编译查看最终生成的代理类$Proxy0,可以理解动态代理类内部实现逻辑
public class $Proxy0 extends Proxy implements IPerson{

    private InvocationHandler handler;

    private static Method m0;
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m4;

    static {
        try {
            m0= Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
            m1 = Class.forName("java.lang.Object").getMethod("toString");
            m2= Class.forName("java.lang.Object").getMethod("hashCode");
            m3 = Class.forName("proxy.Person").getMethod("getSex");
            m4 = Class.forName("proxy.Person").getMethod("setSex", Integer.class);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    protected $Proxy0(@NonNull InvocationHandler h) {
        super(h);
        this.handler=h;
    }

    /*
     * equals,hashCode方法是一样的道理
     */
    @NonNull
    @Override
    public String toString() {
        try {
            return (String) handler.invoke(this,m1,null);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return super.toString();
    }

    @Override
    public void setSex(int sex) throws Throwable {
        handler.invoke(this,m4,new Object[]{sex});
    }

    @Override
    public int getSex() throws Throwable {
        return (int) handler.invoke(this,m3,null);
    }
}

上一篇下一篇

猜你喜欢

热点阅读