zoukankan      html  css  js  c++  java
  • 动态代理Java实现

    思考:在IBuyWatermelon添加一个方法selectWatermelon()

    静态代理中需要在RealSubject中实现该方法,而且Proxy也要实现该方法调用RealSubject中的实现,如果再增加10个方法还是得这样操作,导致大量的代码重复。

    现在来看动态代理(顾名思义,是在运行时才形成的代理对象,不像静态代理在编译时就载入代理对象)。

    生成动态代理的方法有很多: JDK中自带的动态代理java.lang.reflect.*, CGlib等

    下面的例子是JDK中自带的动态代理java.lang.reflect.*

    IBuyWatermelon():接口

    package com.maggie.dynamicproxy;
    
    public interface IBuyWatermelon {
        //代理事件
        public abstract String buyWatermelon();
        
        public abstract void selectWatermelon();
    }

    BuyWatermelonImpl:实现类

    package com.maggie.dynamicproxy;
    
    //可理解成被代理者
    public class BuyWatermelonImpl implements IBuyWatermelon {
    
        private Supermarket supermaket;
        
        public BuyWatermelonImpl(Supermarket supermaket) {
            super();
            this.supermaket = supermaket;
        }
    
        @Override
        public String buyWatermelon() {
            System.out.println("在"+supermaket.getName()+" 买西瓜");
            return "watermelon";
        }
    
        @Override
        public void selectWatermelon() {
            System.out.println("选择无籽西瓜");
        }
    
    }

    ProxyFactory:代理对象类(核心代码)

    package com.maggie.dynamicproxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyFactory {
         //维护一个目标对象
        private Object target;
        public ProxyFactory(Object target){
            this.target=target;
        }
    
       //给目标对象生成代理对象
        public Object getProxyInstance(){
            //动态代理的核心,涉及到反射
            return Proxy.newProxyInstance(
                    target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                //执行目标对象方法
                                Object returnValue = method.invoke(target, args);
                                return returnValue;
                        }
                    }
            );
        }
    
    }

    客户端调用

    package com.maggie.dynamicproxy;
    
    
    public class Main {
        public static void main(String[] args) {
            Supermarket zhaoLiu = new Supermarket();
            zhaoLiu.setName("赵六超市");
            IBuyWatermelon target  = new BuyWatermelonImpl(zhaoLiu);//被代理的对象
            
            
            //创建代理对象
            IBuyWatermelon hourskeeper = (IBuyWatermelon) new ProxyFactory(target).getProxyInstance();
            
            hourskeeper.buyWatermelon();
            hourskeeper.selectWatermelon();
            
        }
    }

    输出

    在赵六超市 买西瓜
    选择无籽西瓜

    现在就算IBuyWatermelon的方法再怎么增加,也只需要在BuyWatermelonImpl实现,就可以在客户端调用,不会出现大量的重复代码。

    从静态代理到动态代理都围绕着卖瓜事件,为了前后方便比较,但是动态代理并没完,里面的源码机制才是核心关键

    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)这个方法是整个动态代理实现的关键

  • 相关阅读:
    文件下载链接
    Python Web服务器
    打印字符串替换
    python 将数据写入excel
    python Telnet通讯
    Python 串口通讯
    monkey 原理,环境搭建、命令详解
    Andriod 四大组件,六大布局
    python练习题100例
    Activity的基本概念与Activity的生命周期
  • 原文地址:https://www.cnblogs.com/maggiejyt/p/7569123.html
Copyright © 2011-2022 走看看