• 设计模式(四)---- 代理模式


     

    代理模式(Proxy Pattern)

    核心作用:通过代理控制对象的访问;可以详细访问某个类或对象的方法,在调用这个方法之前做前置处理,调用这个方法之后做后置处理;(AOP的微实现)

    核心角色:

      (1)抽象角色:定义代理角色和真实角色的公共对外方法;

      (2)真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用;(关注真正的业务逻辑)

      (3)代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法并附加自己的操作;将统一的流程控制放到代理角色中处理。

    应用场景:

      安全代理:屏蔽堆真实角色的直接访问;

      远程代理:通过代理类处理远程方法调用(RMI);

      延时加载:先加载轻量级的代理对象,真正需要时在加载真实对象。

             

    分类:

      静态代理(静态定义代理类)

        动态代理(动态生成代理类)

        JDK自带的动态代理;

        java assist 字节码操作实现;

        CGLIB

        ASM(底层使用指令,可维护性较差)

    一、静态代理模式

    抽象角色:

    public interface Star
    {
        void confer();      //面谈
        void signContract();//签合同
        void bookTicket();  //订票
        void sing();        //唱歌
        void collectMoney();//收钱
    }

    真实角色:

    public class RealStar implements Star
    {
        @Override
        public void confer()
        {
            System.out.println("RealStar.confer()");
        }
    
        @Override
        public void signContract()
        {
            System.out.println("RealStar.signContract()");
        }
    
        @Override
        public void bookTicket()
        {
            System.out.println("RealStar.bookTicket()");
        }
    
        @Override
        public void sing()
        {
            System.out.println("RealStar.sing(周杰伦)");
        }
    
        @Override
        public void collectMoney()
        {
            System.out.println("RealStar.collectMoney()");
        }
    }

    代理角色:

    public class ProxyStar implements Star
    {
        private Star star;
    
        public ProxyStar(Star star)
        {
            this.star = star;
        }
    
        @Override
        public void confer()
        {
            System.out.println("ProxyStar.confer()");
        }
    
        @Override
        public void signContract()
        {
            System.out.println("ProxyStar.signContract()");
        }
    
        @Override
        public void bookTicket()
        {
            System.out.println("ProxyStar.bookTicket()");
        }
    
        @Override
        public void sing()
        {
            star.sing();
        }
    
        @Override
        public void collectMoney()
        {
            System.out.println("ProxyStar.collectMoney()");
        }
    }

    测试代码:

    public class Test
    {
        public static void main(String[] args)
        {
            RealStar realStar = new RealStar();
           Star star = new ProxyStar(realStar);
    
            star.confer();
            star.signContract();
            star.bookTicket();
            star.sing();    //
            star.collectMoney();
        }
    }

    二、动态代理(Dynamic Proxy)

    动态代理相比于静态代理的优点:

    抽象角色(接口)中声明的所有方法都被转移到调用处理器一个集中的方法中,这样我们可以使用更加灵活统一的处理众多的方法。

    1、JDK自带的类

    (1)动态代理需要的处理

      java.lang.reflect.InvocationHandler (处理器接口):可以通过 invoke 方法实现对真实对象的代理访问;每次通过Proxy生成的代理类对象时都有指定代理器对象。

      java.lang.reflect.Proxy : 生成代理类和对象。

    (2)代码实现:抽象角色、真实角色同上

    代理角色:

    public class ProxyStar implements InvocationHandler
    {
        private Star star;
    
        public ProxyStar(Star star)
        {
            this.star = star;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable
        {
            Object object = null;
    
            System.out.println("签合同");
            System.out.println("定机票");
            if("sing".equals(method.getName()))  //执行的方法名为sing时, 调用真实角色的sing方法
            {
                object = method.invoke(star, args);
            }
            System.out.println("最后的方法执行");
            return object;
        }
    }

    测试类代码:

    public class Test
    {
        public static void main(String[] args)
        {
            Star realStar = new RealStar();
            InvocationHandler invocationHandler = new ProxyStar(realStar);
    
            //生成代理对象
            Star proxy = (Star) Proxy.newProxyInstance(
                    RealStar.class.getClassLoader(), //ClassLoader.getSystemClassLoader(),
                    RealStar.class.getInterfaces(),  //new Class[]{Star.class},
                    invocationHandler);
    
            //只要调用了代理对象的任何一个方法都会进入 InvocationHandler 实现类的 invoke() 方法
            proxy.sing();
        }
    }
  • 相关阅读:
    单击按钮左键弹起菜单
    高亮选中MEMO某一行
    DelphiTXT文档编辑器
    桌面名人名言
    判断richtextbox选中的是否为图片
    数组
    解决Linux下IDEA无法使用ibus输入法的问题和tip乱码
    Spring实现AOP的多种方式
    java术语(PO/POJO/VO/BO/DAO/DTO)
    idea intellij对Spring进行单元测试
  • 原文地址:https://www.cnblogs.com/yufeng218/p/9950024.html
Copyright © 2020-2023  润新知