设计模式-代理模式

大家好我是苏麟 , 今天聊聊代理模式 .

此系列全是帮忙宣传 , 原创放在下面了 .

代理模式

代理模式 Proxy Pattern 是⼀种结构型设计模式,⽤于控制对其他对象的访问。 在代理模式中,允许⼀个对象(代理)充当另⼀个对象(真实对象)的接⼝,以控制对这个对象的访问。通常⽤于 在访问某个对象时引⼊⼀些间接层(中介的作⽤),这样可以在访问对象时添加额外的控制逻辑,⽐如限制访问权 限,延迟加载。 ⽐如说有⼀个⽂件加载的场景,为了避免直接访问"⽂件"对象,我们可以新增⼀个代理对象,代理对象中有⼀个对 "⽂件对象"的引⽤,在代理对象的 load ⽅法中,可以在访问真实的⽂件对象之前进⾏⼀些操作,⽐如权限检查, 然后调⽤真实⽂件对象的 load ⽅法,最后在访问真实对象后进⾏其他操作,⽐如记录访问⽇志。

基本实现 : 静态代理

java 复制代码
// 1. 定义抽象主题
interface Subject {
    void request();
}
java 复制代码
// 2. 定义真实主题
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject handles the request.");
    }
}
java 复制代码
// 3. 定义代理
class Proxy implements Subject {
    // 包含⼀个引⽤
    private RealSubject realSubject;
    @Override
    public void request() {
        // 在访问真实主题之前可以添加额外的逻辑
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        // 调⽤真实主题的⽅法
        realSubject.request();
        // 在访问真实主题之后可以添加额外的逻辑
    }
}
java 复制代码
// 4. 客户端使⽤代理
public class Main {
    public static void main(String[] args) {
        // 使⽤代理
        Subject proxy = new Proxy();
        proxy.request();
    }
}

基本实现 : 动态代理

给个视频 : 【黑马磊哥】Java动态代理深入剖析,真正搞懂Java核心设计模式:代理设计模式_哔哩哔哩_bilibili

java 复制代码
/**
 * 接口
 */
public interface Star {
    String sing(String name);

    void dance();
}
java 复制代码
/**
 * 对象类
 * <p>
 * 动态代理需要实现接口
 */
public class BigStar implements Star {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String sing(String name) {
        System.out.println(this.name + "正在唱 : " + name);
        return "谢谢大家 !";
    }

    public void dance() {
        System.out.println(this.name + "正在跳舞____ ");
    }
}
java 复制代码
/**
 * 代理类
 */
public class ProxyUtils {
    /**
     * 产生代理
     *
     * @param bigStar 产生谁的代理
     * @return 产生的代理一定是实现Star的对象
     */
    public static Star proxyCreate(BigStar bigStar) {
/**
 * ClassLoader loader, //用于指定一个类加载器 (用这个加载器加载生成的代
 理类)
 * Class<?>[] interfaces, //生成的代理长什么样子,也就是那些实现方法
 * InvocationHandler h //生成的代理要干什么事情
 */
//产生一个BigStar代理对象
        Star star = (Star)
                Proxy.newProxyInstance(ProxyUtils.class.getClassLoader(), new Class[]
                        {Star.class}, new InvocationHandler() {
                    @Override //回调方法
                    public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {
                        if (method.getName().equals("sing")) {
                            System.out.println("准备话筒,收钱!");
                        } else if (method.getName().equals("dance")) {
                            System.out.println("准备场地,收钱!");
                        }
                        return method.invoke(bigStar, args);
                    }
                });
        return star;
    }
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        BigStar star = new BigStar();
        star.setName("张杰");
        Star s = ProxyUtils.proxyCreate(star);
        System.out.println(s.sing("逆战"));
    }
}
______________________________________________________
准备话筒,收钱!
张杰正在唱 : 逆战
谢谢大家 !

使用场景

代理模式可以控制客户端对真实对象的访问,从⽽限制某些客户端的访问权限,此外代理模式还常⽤在访问真实对 象之前或之后执⾏⼀些额外的操作(⽐如记录⽇志),对功能进⾏扩展。

  • 虚拟代理:当⼀个对象的创建和初始化⽐较昂贵时,可以使⽤虚拟代理,虚拟代理可以延迟对象的实际创建和 初始化,只有在需要时才真正创建并初始化对象
  • 安全代理:安全代理可以根据访问者的权限决定是否允许访问真实对象的⽅法

但是代理模式涉及到多个对象之间的交互,引⼊代理模式会增加系统的复杂性,在需要频繁访问真实对象时,还可 能会有⼀些性能问题。

代理模式在许多⼯具和库中也有应用:

  • Spring 框架的 AOP 模块使⽤了代理模式来实现切⾯编程。通过代理,Spring 能够在⽬标对象的⽅法执⾏ 前、执⾏后或抛出异常时插⼊切⾯逻辑,⽽不需要修改原始代码
  • Java 提供了动态代理机制,允许在运⾏时⽣成代理类
  • Android中的Glide框架使⽤了代理模式来实现图⽚的延迟加载

原创地址 : GitHub - youngyangyang04/kama-DesignPattern: 卡码网-23种设计模式精讲,每种设计模式都配套代码练习题,支持 Java,CPP,Python,Go

了解更多 : 【黑马磊哥】Java动态代理深入剖析,真正搞懂Java核心设计模式:代理设计模式_哔哩哔哩_bilibili

这期就到这里,下期见!

相关推荐
Penge6667 小时前
Go 接口编译期断言
后端
我是一颗柠檬7 小时前
【MySQL全面教学】MySQL面试高频考点汇总Day15(2026年)
数据库·后端·mysql·面试
橙淮8 小时前
并发编程(六)
java·jvm
拽着尾巴的鱼儿8 小时前
springboot openfeign 自定义feign 接口重试机制
java·spring boot·后端
白露与泡影8 小时前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
Ceelog8 小时前
久坐党自救指南:屏幕前 8 小时,身体到底在经历什么
前端·后端
EntyIU9 小时前
JVM内存与GC笔记
java·jvm·笔记
XS0301069 小时前
并发编程 六
java·后端
yaoxin5211239 小时前
419. 现代 Java IO 最佳实践 - 写入文本文件
java·windows·python
雪宫街道9 小时前
synchronized 锁的范围:对象锁、类锁与代码块锁
java·jvm·后端·面试