跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Spring 动态代理详解

Spring 动态代理是框架底层的核心机制之一。它利用 JDK 的 Proxy 类和 InvocationHandler 接口,在运行时动态生成代理类,而非编译期硬编码。这种方式允许在不修改原有业务代码的前提下,统一添加日志、事务等横切关注点。相比静态代理,动态代理减少了重复代码,提升了扩展性和维护效率,是理解 Spring AOP 的基础。

星河入梦发布于 2025/2/5更新于 2026/9/1065 浏览
Spring 动态代理详解

什么是动态代理

先聊聊动态代理的概念,以及它和静态代理到底有什么不同。虽然两者在角色属性上相似,但代理类的实现方式截然不同。静态代理是我们提前写好代理类,而动态代理的代理类是在运行时动态生成的。

理解代理模式,得先搞清楚几个关键角色:

  • 抽象角色:通常由接口或抽象类定义。
  • 真实角色:被代理的实际对象。
  • 真实角色:被代理的实际对象。
  • 代理角色:负责代理真实角色,并在前后执行附属操作。
  • 客户:访问代理对象的调用方。

动态代理的分类

常见的实现方式主要有三类:

  1. 基于接口的动态代理:JDK 原生支持。
  2. 基于类的动态代理:如 CGLIB。
  3. 字节码实现:如 Javassist。

这里我们聚焦于 JDK 原生提供的动态代理机制,这也是 Spring AOP 默认使用的方案。

JDK 动态代理核心组件

要玩转 JDK 动态代理,主要涉及两个核心部分:

Proxy 类

这是动态代理类的超类,提供了创建代理实例的静态方法。所有的动态代理类都继承自它。

InvocationHandler 接口

这是代理实例的调用处理程序接口。当你调用代理对象的方法时,实际会触发这个接口中的 invoke 方法。

实战演示

为了更直观地理解,我们来看一个完整的 Demo 流程。

1. 定义接口与实现

首先需要一个业务接口和对应的实现类。注意命名规范,避免拼写错误。

package com.example.demo;

public interface UserService {
    void add();
    void delete(); // 修正了原文 delate 拼写
    void update();
    void query();
}
package com.example.demo;

public class UserServiceImpl implements UserService {
    
       {
        System.out.println();
    }

    
       {
        System.out.println();
    }

    
       {
        System.out.println();
    }

    
       {
        System.out.println();
    }
}
@Override
public
void
add
()
"增加了一名用户"
@Override
public
void
delete
()
"删除了一名用户"
@Override
public
void
update
()
"修改了一名用户"
@Override
public
void
query
()
"查找用户"

2. 编写调用处理器

这是最关键的一步。我们需要实现 InvocationHandler 接口,在这里决定代理对象被调用时具体做什么。

package com.example.demo.proxy;

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 setTarget(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 {
        // 前置处理:比如记录日志
        System.out.println("执行了 " + method.getName() + " 方法");
        
        // 核心逻辑:反射调用真实对象的方法
        Object result = method.invoke(target, args);
        
        // 后置处理
        return result;
    }
}

这里有个细节要注意:invoke 方法里的 method.invoke(target, args) 才是真正执行业务逻辑的地方。我们在它前后加入的逻辑,就是所谓的'横切关注点'。

3. 客户端调用

最后,客户端只需要持有代理对象,就像使用普通对象一样。

package com.example.demo.client;

import com.example.demo.UserService;
import com.example.demo.UserServiceImpl;
import com.example.demo.proxy.ProxyInvocationHandler;

public class Client {
    public static void main(String[] args) {
        // 真实角色
        UserServiceImpl userService = new UserServiceImpl();

        // 创建代理处理器
        ProxyInvocationHandler handler = new ProxyInvocationHandler();
        handler.setTarget(userService);

        // 获取代理对象
        UserService proxy = (UserService) handler.getProxy();
        
        // 调用代理方法
        proxy.add();
    }
}

总结

与静态代理不同,在这个实例中我们没有手动创建具体的代理类,而是让动态代理机制在运行时自动生成。这意味着多个不同的真实角色可以复用同一个代理类,极大地提高了开发效率。这种灵活性正是 Spring 能够轻松实现 AOP 等功能的基础。

目录

  1. 什么是动态代理
  2. 动态代理的分类
  3. JDK 动态代理核心组件
  4. Proxy 类
  5. InvocationHandler 接口
  6. 实战演示
  7. 1. 定义接口与实现
  8. 2. 编写调用处理器
  9. 3. 客户端调用
  10. 总结

更多推荐文章

查看全部
  • 企业投融资模式与法律风险分析
  • 大模型微调必要性分析:LoRA 与 RAG 方案对比
  • 无人机目标检测中的自适应图像变焦与边界框变换
  • C++ 内存管理:new/delete 操作自定义类型的构造与析构原理
  • Google Antigravity AI 编程工具下载与安装指南
  • OpenClaw v2026.3.8 部署与配置实操
  • Kimi Code:Moonshot AI 智能编程助手及 CLI 集成
  • WebStorm 2023 安装与使用教程
  • HS-FPN:微小目标检测的频域与空间感知架构
  • AI绘画实战:从DALL·E 3到Stable Diffusion 3,手把手教你搭建自己的AI画室(含ControlNet配置)
  • Linux 进程控制详解
  • MFDA-YOLO:面向无人机小目标检测的多尺度特征融合与动态对齐网络
  • GitHub Copilot 网络配置与代理优化实战指南
  • VibeThinker-1.5B 快速部署:3 分钟搭建编程助手
  • C++ 虚继承
  • 基于 AI 辅助的高校宿舍管理系统设计与实现
  • Stable Diffusion 视觉提示词注入攻击原理与实现分析
  • 大模型技术对汽车行业的影响与变革
  • Google 发布 Gemini Embedding 2 及 MuleRun 自进化 AI 助手动态
  • Spring Boot ResponseEntity 响应处理与文件下载实战

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online