• 结构型模式 -- 代理模式(静态代理&动态代理)


    静态代理:

      真实角色和代理角色实现相同的接口,代理角色拥有真实角色的引用。代理角色去执行方法,对于某些“真正”需要真实角色自己执行的方法时,在代理角色内部就调用真实角色的方法,其他的就可以执行代理角色的方法(例如房主和中介,有带领客户看房,签合同,交钱,收房等方法,那么签合同、交钱就是“真正”需要真实角色自己执行的方法,其他的方法就可以直接交给中介去执行)

     应用场景:

    1)安全代理:屏蔽对真实角色的直接访问

    2)延迟加载:先加载轻量级的代理对象,真正需要时再加载真实对象

    动态代理:

    实现方式有:JDK自带的动态代理;    javaassist字节码操作库实现;CGUB;ASM

    JDK自动的动态代理:

    代码实现:

    // 接口
    public interface IAccount {
        IAccount deposit(double money);
        double getBalance();
    }
    // 真实角色
    public class Account implements IAccount{
        private double balance = 100;
        @Override
        public IAccount deposit(double money) {
            balance += money;
            return null;
        }
        @Override
        public double getBalance() {
            return balance;
        }
    
    }
    // 处理器
    public class AccountHandler implements InvocationHandler{
        IAccount account;
        public AccountHandler(IAccount account) {
            this.account = account;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if("deposit".equals(method.getName())) {
                method.invoke(account, args);
                return proxy;
            }else {
                return method.invoke(account, args);
            }
        }
    
    }
    // 应用
    public class Client02 {
        public static void main(String[] args) {
            IAccount account = new Account();
            AccountHandler handler = new AccountHandler(account);
            IAccount proxy = (IAccount) Proxy.newProxyInstance(account.getClass().getClassLoader(), account.getClass().getInterfaces(), handler);
            IAccount proxy1 = proxy.deposit(100);
            double b = proxy.getBalance();
            System.out.println(b);
        }
    }

    结果:

    可以看到在处理器那个代码里面,invoke()里面的两处的返回有些不同,一般的就直接一句代码:return method.invoke(account, args)

    这里写这么多是为了体现 public Object invoke(Object proxy, Method method, Object[] args) 参数proxy 的作用:

    取至源码(对invoke()方法的说明):

    意思: 1:当一个方法在代理对象上被调用 will be(实际上是) 在 invocation handler上调用

                 2: method是在参数proxy 上被调用

    proxy  <-------> this

    // 将上面代码的应用部分改成:
    public class Client02 {
        public static void main(String[] args) {
            IAccount account = new Account();
            AccountHandler handler = new AccountHandler(account);
            IAccount proxy = (IAccount) Proxy.newProxyInstance(account.getClass().getClassLoader(), account.getClass().getInterfaces(), handler);
            proxy.deposit(100).deposit(200);
            double b = proxy.getBalance();
            System.out.println(b);
        }
    }

    结果:

    静态代理需要自定义代理对象,动态代理是动态生成代理对象

  • 相关阅读:
    java中BigDecimal的四舍五入小记
    thinking in java学习笔记:14章 类型信息
    java中==和equals
    java中值传递和引用传递
    java中的赋值
    hessian学习笔记
    springboot学习笔记:12.解决springboot打成可执行jar在linux上启动慢的问题
    要是满足下面的其中3种情况,你就跑路吧
    vim程序编辑器---常用操作整理
    报错end Kernel panic
  • 原文地址:https://www.cnblogs.com/DDiamondd/p/10975671.html
Copyright © 2020-2023  润新知