JDK动态代理源码解析——Proxy、WeakCache、ProxyGenerator

  1. JDK版本为RedHat OpenJDK 1.8.0_282

  2. JDK中的动态代理Proxy类仅限于方法拦截,且只能代理实现了接口的对象

  3. 调用Proxy的静态方法创建——继承了Proxy类的代理类(java只支持单继承,这就是为什么要求被代理类必须实现接口),通过该代理类的构造器创建对应代理对象,该对象实现了被代理类的接口,仅起到接口的作用。

  4. 代理类对象内持有一个——实现了InvocationHandler接口的对象(我们称它为中间对象吧)的引用,中间对象又持有一个被代理对象的引用。中间对象是真正办事的对象,对代理类对象的所有方法调用都会转发给中间对象,由中间对象的invoke方法实现,而中间对象的 invoke 方法,通过反射调用了被代理对象的对应方法

  5. 以上是从整体的角度介绍,下面从介绍下具体代码

    interface Animal{
         
        public void speak();
    }
    class Dog implements Animal{
         
        @Override
        public void speak() {
         
            System.out.println("I am a dog.");
        }
    }
    class DogHandler implements InvocationHandler{
         
        private Object obj;
        public dogHandler(Object obj){
         
            this.obj = obj;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         
            System.out.println("In a handler.");
            method.invoke(obj, args);
            System.out.println(obj.toString());
            return proxy;
        }
    }
    public class test {
         
        public static void main(String[] args) throws IllegalAccessException,
                InstantiationException, NoSuchMethodException, InvocationTargetException {
         
            Dog aDog = new Dog();
            DogHandler h = new DogHandler(aDog);
    
    //        Animal pxyDog = (Animal) Proxy.newProxyInstance(dog.class.getClassLoader(),
    //                                                dog.class.getInterfaces(), h);
    
            Class pxyDogClazz = Proxy.getProxyClass(Dog.class.getClassLoader(), Dog.class.getInterfaces());
            Constructor pxyDogCons = pxyDogClazz.getConstructor(InvocationHandler.class);
            Animal pxyDog = (Animal) pxyDogCons.newInstance(h);
    
            pxyDog.speak();
        }
    }
    
  6. Proxy提供了两种方式创建代理对象,getProxyClass()创建代理类 + getConstructor() 反射获取构造器对象 + newInstance()创建实例,以及将其与对应对应异常处理代码打包在一块的,newProxyInstance()。

  7. getProxyClass() 接受类加载器与接口类型,实质是在内部调用getProxyClass0(),而后者则是向内部成员 proxyClassCache 申请,proxyClassCache 是一个缓存,如果之前创建过对应的代理类,则直接返回,否则创建。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值