• 代理模式


    10. 代理模式

    代理模式是SpringAOP的底层!【SpringAOP和SpringMVC】

    • 代理模式的分类:静态代理 动态代理

    10.1 静态代理

    角色分析:

    • 抽象角色:一般会使用接口或者抽象类来解决

      package com.peng.demo01;
      
      //租房
      public interface Rent {
          public void rent();
      }
      
    • 真实角色:被代理的角色

      package com.peng.demo01;
      
      //房东
      public class Host implements Rent{
          @Override
          public void rent() {
              System.out.println("房东要出租房子!");
          }
      }
      
    • 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作

      package com.peng.demo01;
      
      public class Proxy implements Rent {
          private Host host;
      
          public Proxy() {
          }
      
          public Proxy(Host host) {
              this.host = host;
          }
      
          @Override
          public void rent() {
              seeHouse();
              host.rent();
              sign();
              fare();
          }
      
          //看房
          public void seeHouse(){
              System.out.println("中介带你看房");
          }
      
          //签合同
          public void sign(){
              System.out.println("签租赁合同");
          }
      
          //收中介费
          public void fare(){
              System.out.println("收中介费");
          }
      }
      
    • 客户端:访问代理对象的人!

      package com.peng.demo01;
      
      public class Client {
          public static void main(String[] args) {
              //房东要租房子
              Host host = new Host();
              //代理,中介帮房东租房子,但是呢?代理一般会有一些附属操作!
              Proxy proxy = new Proxy(host);
              //你不用面对房东,直接找中介租房即可
              proxy.rent();
          }
      }
      

    代理模式的好处:

    • 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
    • 公共也就就交给代理角色!实现了业务的分工
    • 公共业务发生扩展的时候,方便集中管理

    缺点:一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低

    10.2 加深理解

    对修改关闭,不修改源码,外边套一层

    10.3 动态代理

    • 动态代理和静态代理角色一样
    • 动态代理的代理类是动态生成的,不是我们直接写好的
    • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
      • 基于接口:JDK动态代理【我们在这里使用】
      • 基于类:cglib
      • java字节码实现:javasist

    需要了解两个类:Proxy 代理,InvocationHandler 调用处理程序

    Rent.java 租房接口

    package com.peng.demo03;
    
    //租房
    public interface Rent {
        public void rent();
    }
    

    Host.java 房东实体类

    package com.peng.demo03;
    
    //房东
    public class Host implements Rent {
        @Override
        public void rent() {
            System.out.println("房东要出租房子!");
        }
    }
    

    ProxyInvocationHandler.java 动态代理类

    package com.peng.demo03;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    //用这个类自动生成代理类
    public class ProxyInvocationHandler implements InvocationHandler{
    
        //被代理的接口
        private Rent rent;
    
        public void setRent(Rent rent) {
            this.rent = rent;
        }
    
        //生成得到代理类
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
        }
    
        //处理代理实力,并返回结果
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
            //动态代理的本质,就是使用反射机制实现
            seeHouse();
            Object result = method.invoke(rent, args);
            fare();
            return result;
        }
    
        public void seeHouse(){
            System.out.println("中介带看房子");
        }
    
        public void fare(){
            System.out.println("收中介费");
        }
    }
    

    Client.java 客户端

    package com.peng.demo03;
    
    public class Client {
        public static void main(String[] args) {
            //真实角色
            Host host = new Host();
    
            //代理角色:现在没有
            ProxyInvocationHandler pih = new ProxyInvocationHandler();
            //通过调用程序处理角色来处理我们要调用的按口对象!
            pih.setRent(host);
    
            Rent proxy = (Rent) pih.getProxy(); //这里的proxy就是动态生成的,我们并没有写
            proxy.rent();
        }
    }
    

    动态代理的好处:

    • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
    • 公共也就就交给代理角色!实现了业务的分工
    • 公共业务发生扩展的时候,方便集中管理
    • 一个动态代理类代理的是一个接口, 一般就是对应的一类业务
    • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可

    通式

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyInvocationHandler implements InvocationHandler{
    
        //被代理的接口
        private Object target;
    
        public void setRent(Object target) {
            this.target = target;
        }
    
        //生成得到代理类
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
        }
    
        //处理代理实力,并返回结果
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //动态代理的本质,就是使用反射机制实现
            log(method.getName()); //利用反射写活了
            Object result = method.invoke(target, args);
            return result;
        }
    
        public void log(String msg){
            System.out.println("执行了"+msg+"方法");
        }
    }
    
  • 相关阅读:
    八数码难题 (codevs 1225)题解
    小木棍 (codevs 3498)题解
    sliding windows (poj 2823) 题解
    集合删数 (vijos 1545) 题解
    合并果子 (codevs 1063) 题解
    等价表达式 (codevs 1107)题解
    生理周期 (poj 1006) 题解
    区间 (vijos 1439) 题解
    区间覆盖问题 题解
    种树 (codevs 1653) 题解
  • 原文地址:https://www.cnblogs.com/peng8098/p/java_17.html
Copyright © 2020-2023  润新知