栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JDK动态代理demo

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JDK动态代理demo

直接上代码:

public interface ShoppingService {
    void shopping();
}

被代理类:

public class ShoppingServiceImpl implements ShoppingService {
    @Override
    public void shopping() {
        System.out.println("shopping……");
    }
}
public class MyHandler implements InvocationHandler {
    private Object target;

    MyHandler(Object target){
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(method.getName().equals("shopping")){
            System.out.println("before shoping……");
            Object result = method.invoke(target,args);		
            System.out.println("after shopping");
            return result;
        }
        return method.invoke(target,args);
    }
}

**Object result = method.invoke(target,args);**这个到后面应该就看得懂了。

public class Client {
    public static void main(String[] args) {
        ShoppingServiceImpl shoppingServiceImpl = new ShoppingServiceImpl();
// 保存代理类的字节码 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); ShoppingService proxy = (ShoppingService) Proxy.newProxyInstance(Client.class.getClassLoader(),shoppingServiceImpl.getClass().getInterfaces(),new MyHandler(shoppingServiceImpl)); proxy.shopping(); } }

运行结果:

探究 Proxy.newProxyInstance方法:

public static Object newProxyInstance(ClassLoader loader,
                                          Class[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);
        final Class[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }
        
        Class cl = getProxyClass0(loader, intfs);
        
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
            final Constructor cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
           
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }

上面的代码被我删减了,主要看这几个:

checkProxyAccess方法中,进行参数验证在getProxyClass0方法中,生成代理类Class或者从proxyClassCache中找已生成过的代理类。通过getConstructor方法,获取生成的代理类的构造方法。通过newInstance方法,生成实例对象,也就是最终的代理对象==$Proxy0==。

代理类:

public final class $Proxy0 extends Proxy implements ShoppingService {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }
    public final void shopping() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }
    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("com.blue.proxy.ShoppingService").getMethod("shopping");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        }
    }
}

  上面代码被我删了很多,主要看shopping方法,里面的super.h.invoke(this, m3, (Object[])null) 去到了父类InvocationHandler,父类的invoke方法早就被MyHandler重写了。

本人理解有限,只是介绍了一个简单的流程。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/759330.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号