zoukankan      html  css  js  c++  java
  • Java中的代理模式--静态代理和动态代理

    代理模式定义:为其他对象提供了一种代理以控制对这个对象的访问。

    代理模式的三种角色:

      Subject抽象主题角色:抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。

      RealSubject具体主题角色:也叫做被委托角色、被代理角色。它才是冤大头,是业务逻辑的具体执行者,Subject接口的实现。

      Proxy代理主题角色:也叫做委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前做预处理和善后工作。

    一句话描述静态代理和动态代理:

      静态代理:一个主题类与一个代理类一一对应。

      动态代理:多个主题类对应一个代理类。

    静态代理的例子:

    Subject接口:

    package com.design.one;
    public interface Subject {
        void doSomething();
    }

    RealSubject类:

    package com.design.one;
    public class RealSubject implements Subject{
        @Override
        public void doSomething() {
            System.out.println("doSomething()......");
        }
    } 

    Proxy类:

    package com.design.one;
    public class Proxy implements Subject{
        Subject subject = null;
        public Proxy(Subject subject) {
            this.subject = subject;
        }
        @Override
        public void doSomething() {
            System.out.println("之前");
            subject.doSomething();
            System.out.println("之后");
        }
    }

     Client类:

    package com.design.one;
    public class Client {
        public static void main(String[] args) {
            Subject sub = new RealSubject();
            Proxy proxy = new Proxy(sub);
            proxy.doSomething();
        }
    }

    输出结果:

      之前
      doSomething()......
      之后

    动态代理的例子:

    引子:一般来说,使用静态代理,都需要每一个RealSubject编写一一对应的代理类,这些类在编译期间就已经确定了的,如果有多个RealSubject类,但是他们的代理类里面的前处理(“之前”)和后处理(“之后”)是一样的,那么使用静态代理模式为多个RealSubject类编写相同的处理逻辑的代理类就显得臃肿了和多余了。而动态代理不同,它能使多个RealSubject类对应一个代理类,共享“前处理,后处理”功能,动态调用所需主题,大大减小了程序规模。

    Subject类:

    package com.design.three;
    public interface Subject {
        void doSomething();
        void doSomething1();
    } 

    Subject2类:

    package com.design.three;
    public interface Subject2 {
        void doSomething3();
        void doSomething4();
    } 

    RealSubject类:

    package com.design.three;
    public class RealSubject implements Subject,Subject2{
    
        @Override
        public void doSomething() {
            System.out.println("doSomething()......");
        }
        @Override
        public void doSomething1() {
            System.out.println("doSomething()1......");  
        }
        @Override
        public void doSomething3() {
            System.out.println("doSomething()3......");
        }
        @Override
        public void doSomething4() {
            System.out.println("doSomething()4......");
        }
    } 

    RealSubject2类:

    package com.design.three;
    public class RealSubject2 implements Subject,Subject2{
        @Override
        public void doSomething() {
            System.out.println("Subject2doSomething()......");
        }
        @Override
        public void doSomething1() {
            System.out.println("Subject2doSomething()1......");   
        }
        @Override
        public void doSomething3() {
            System.out.println("Subject2doSomething()3......");
        }
        @Override
        public void doSomething4() {
            System.out.println("Subject2doSomething()4......");
        }
    }

     MyInvocationHandler类:

    package com.design.three;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    public class MyInvocationHandler implements InvocationHandler{
        private Object obj = null;
        public MyInvocationHandler(Object obj) {
            this.obj = obj;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            System.out.println("方法前....");
            return method.invoke(obj, args);
        }
    }

     Client类:

    package com.design.three;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    public class Client {
        public static void main(String[] args) {
            Subject sub = new RealSubject();//1
            // Subject sub = new RealSubject2();//2
            InvocationHandler handler = new MyInvocationHandler(sub);
            Subject proxy = (Subject) Proxy.newProxyInstance(sub.getClass()
                    .getClassLoader(), sub.getClass().getInterfaces(), handler);
            proxy.doSomething();
        }
    }

     输出结果:

    方法前....
    doSomething()......

    把2注释打开,1注释掉,输出结果:

    方法前....
    Subject2doSomething()......

    接下来是四篇个人认为比较好的学习动态代理的文章,具体原理和分析都在下面了,我就不再累赘了:

    Java帝国之动态代理

    动态代理和静态代理到底有什么区别,好处在哪里?

    JDK动态代理实现原理

    Java设计模式——代理模式实现及原理

  • 相关阅读:
    linux command line send email
    js的小随笔
    JavaScript的严格模式
    nodejs学习笔记<六>文件处理
    nodejs学习笔记<五>npm使用
    nodejs学习笔记<四>处理请求参数
    nodejs学习笔记<三>关于路由(url)
    nodejs学习笔记<一>安装及环境搭建
    转:HTTP 301 跳转和302跳转的区别
    前端代码新写法——Zen Coding
  • 原文地址:https://www.cnblogs.com/tongkey/p/8596697.html
Copyright © 2011-2022 走看看