设计模式(九)_代理模式

简介: 不知不觉今天已经7月底了,时间过得真快,这个月真热,这篇文章主要来介绍代理模式。概述代理模式为另一个对象提供一个替身或者占位符以控制对这个对象的访问如下图所示UML类图代理模式类别代码实现这里是结合springAop,仿造它的实现静态代理public interfac...

不知不觉今天已经7月底了,时间过得真快,这个月真热,这篇文章主要来介绍代理模式。

概述

代理模式为另一个对象提供一个替身或者占位符以控制对这个对象的访问

如下图所示

img_883d52675407cf9762531b63bb124848.png

UML类图

img_c5e2d856653bfe58c24bbb0355a94696.png

代理模式类别

img_f3b76f994df79810357753ad791ede77.png

代码实现

这里是结合springAop,仿造它的实现

静态代理

public interface Subject {

    void request();
}


// 请求的真实目标对象
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("real subject execute request");
    }
}


// 代理对象
public class Proxy implements Subject {

    private RealSubject realSubject;

    public Proxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public void request() {
        System.out.println("before");
        try {
            realSubject.request();
        } catch (Exception e) {
            System.out.println("ex:" + e);
            throw e;
        } finally {
            System.out.println("after");
        }


    }
}

客户端调用代码

public class Client {

    public static void main(String[] args) throws Exception {
        Subject subject = new Proxy(new RealSubject());

        subject.request();

    }
}

运行结果

before
real subject execute request
after

静态代理有一个很明显的缺点:代理的方法越多,重复代码越多。
就不符合DRY原则。于是 就产生了动态代理

动态代理

jdk代理

JDK 为我们提供了一种动态代理的实现,通过实现 InvocationHandler 接口来实现动态代理。

代理类代码

public class JdkProxySubject implements InvocationHandler {

    private RealSubject realSubject;

    public JdkProxySubject(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before");
        Object result = null;
        try {
            result = method.invoke(realSubject, args);
        } catch (Exception e) {
            System.out.println("ex" + e);
            throw e;
        } finally {
            System.out.println("after");
        }


        return result;
    }
}

客户端类代码

public class Client {

    public static void main(String[] args) throws Exception {
        Subject subject = (Subject) Proxy.newProxyInstance(Client.class
                .getClassLoader(), new Class[]{Subject.class}, new JdkProxySubject(new RealSubject()));

        subject.request();

    }
}

运行结果

before
real subject execute request
after

上面讲了动态代理是解决代码重复的问题。我们来验证下

首先,在Subject 接口中增加一个hello方法

public interface Subject {

    void request();

    void hello();
}


public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("real subject execute request");
    }

    @Override
    public void hello() {
        System.out.println("real subject execute hello");
    }
}

静态代理类 如果想要代理hello 这个方法。就要在代理类中实现这个方法

public class Proxy implements Subject {

    private RealSubject realSubject;

    public Proxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }


    @Override
    public void hello() {
        ...
    }
}

我们看动态代理类,无需改变,直接运行测试类

public class Client {

    public static void main(String[] args) throws Exception {
        Subject subject = (Subject) Proxy.newProxyInstance(Client.class
                .getClassLoader(), new Class[]{Subject.class}, new JdkProxySubject(new RealSubject()));

        subject.hello();

    }
}

运行结果

before
real subject execute hello
after
Cglib代理

代理类

public class DemoMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("before in cglib");
        Object result = null;
        try {
            result = proxy.invokeSuper(object,args);
        }catch (Exception e){
            System.out.println("get ex :" + e.getMessage());
            throw e;
        }finally {
            System.out.println("after in cglib");
        }
        return result;
    }
}

调用

public class Client {

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RealSubject.class);
        enhancer.setCallback(new DemoMethodInterceptor());
        Subject subject = (Subject) enhancer.create();
        subject.request();
    }
}

运行结果

before in cglib
real subject execute request
after in cglib

JDK代理和Cglib代理区别

  • JDK代理只能针对有接口的类的方法进行代理
  • Cglib基于继承来实现代理,无法对static、final 类进行代理
  • Cglib基于继承来实现代理,无法对private、static 方法 进行代理

代理模式暂时先分析到这,玩的开心!

学习不是要么0分,要么100分的。80分是收获;60分是收获;20分也是收获。有收获最重要。但是因为着眼于自己的不完美,最终放弃了,那就是彻底的0分了。
相关文章
|
7月前
|
设计模式 Java 数据库连接
【设计模式】【结构型模式】代理模式(Proxy)
一、入门 什么是代理模式? 代理模式(Proxy Pattern)是一种结构型设计模式,允许你提供一个代理对象来控制对另一个对象的访问。 代理对象在客户端和目标对象之间起到中介作用,可以在不改变目标对
196 10
|
11月前
|
设计模式 缓存 Java
「全网最细 + 实战源码案例」设计模式——代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,通过代理对象控制对目标对象的访问并添加额外功能。它分为静态代理和动态代理,后者包括JDK动态代理和CGLIB动态代理。JDK动态代理基于接口反射生成代理类,而CGLIB通过继承目标类生成子类。代理模式适用于延迟初始化、访问控制、远程服务、日志记录和缓存等场景,优点是职责分离、符合开闭原则和提高安全性,缺点是增加系统复杂性。
275 25
|
设计模式 Java
Java一分钟之-设计模式:装饰器模式与代理模式
【5月更文挑战第17天】本文探讨了装饰器模式和代理模式,两者都是在不改变原有对象基础上添加新功能。装饰器模式用于动态扩展对象功能,但过度使用可能导致类数量过多;代理模式用于控制对象访问,可能引入额外性能开销。文中通过 Java 代码示例展示了两种模式的实现。理解并恰当运用这些模式能提升代码的可扩展性和可维护性。
186 1
|
设计模式 Java 数据库连接
【重温设计模式】代理模式及其Java示例
【重温设计模式】代理模式及其Java示例
|
12月前
|
设计模式 前端开发 数据安全/隐私保护
前端必须掌握的设计模式——代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,通过引入“替身”对象来间接访问真实对象,从而解耦并提升性能和安全性。例如,知名艺人复出后,经纪人作为代理筛选商单,确保只处理符合团队利益的请求。代码实现中,定义接口`IService`,艺人和经纪人都实现该接口,经纪人在访问时进行过滤和转发。代理模式常用于权限控制、性能优化等场景,如前端中的Tree-shaking和ES6的Proxy构造方法。
前端必须掌握的设计模式——代理模式
|
设计模式 缓存 安全
设计模式——代理模式
静态代理、JDK动态代理、Cglib 代理
设计模式——代理模式
|
设计模式 缓存 Java
【十一】设计模式~~~结构型模式~~~代理模式(Java)
文章详细介绍了代理模式(Proxy Pattern),这是一种对象结构型模式,用于给对象提供一个代理以控制对它的访问。文中阐述了代理模式的动机、定义、结构、优点、缺点和适用环境,并探讨了远程代理、虚拟代理、保护代理等不同代理形式。通过一个商务信息查询系统的实例,展示了如何使用代理模式来增加身份验证和日志记录功能,同时保持客户端代码的无差别对待。此外,还讨论了代理模式在分布式技术和Spring AOP中的应用,以及动态代理的概念。
【十一】设计模式~~~结构型模式~~~代理模式(Java)
|
设计模式 Java 数据安全/隐私保护
Java设计模式-代理模式(7)
Java设计模式-代理模式(7)
125 2
|
设计模式
设计模式的基础问题之代理模式在工作中的问题如何解决
设计模式的基础问题之代理模式在工作中的问题如何解决
126 0
|
设计模式 算法 Go
iLogtail设计模式问题之代理模式在iLogtail中是如何应用的
iLogtail设计模式问题之代理模式在iLogtail中是如何应用的

热门文章

最新文章