静态代理和动态代理

静态代理

一、什么是代理(Proxy)?

代理的意思很简单:

"不让你直接找目标对象,而是通过中间人(代理)去访问。"

就像明星不直接接电话,而是通过经纪人(代理人)来沟通。


🧱 二、一个最简单的例子(静态代理)

我们先写一个接口 和一个真正干活的类

csharp 复制代码
// 抽象主题(接口)
public interface UserService {
    void addUser();
}
​
// 真实主题(被代理类)
public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("执行添加用户的逻辑");
    }
}
​

现在我们想在执行 addUser() 之前打印日志。 如果你直接改 UserServiceImpl,就破坏了它的纯净性。

于是我们写一个「代理类」👇

🤵 三、静态代理类实现

csharp 复制代码
// 代理类
public class UserServiceProxy implements UserService {
    private UserService target; // 持有真实对象的引用
​
    public UserServiceProxy(UserService target) {
        this.target = target;
    }
​
    @Override
    public void addUser() {
        System.out.println("前置操作:开始记录日志");
        target.addUser();  // 调用目标对象的方法
        System.out.println("后置操作:操作成功");
    }
}
​

🚀 四、使用

java 复制代码
public class Test {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        UserService proxy = new UserServiceProxy(userService);
​
        proxy.addUser();
    }
}
​

动态代理(将接口代理出去,实现这个接口的调用方法,都会执行代理内部的方法)

动态代理的核心就是在内存中动态生成一个代理类,这个类实现了指定接口,所有方法调用最终都会转发到 InvocationHandler 的 invoke() 方法中。

"定义一个接口 → 动态生成代理类实现接口 → 通过反射执行 SQL 并返回结果"

在手写mybatis-plus源码中如何实现

定义一个通用接口,这个接口里面有增删改查泛型,然后里面的所有都会被代理

然后的话先把继承这个接口的都进行代理,这样内部调用的方法都会通过调用反射的sql来实现

核心方法

loader:类加载器,用来加载生成的代理类;

interfaces:要实现的接口(比如 UserMapper);

h:你的回调处理器,实现了 InvocationHandler 接口。

vbnet 复制代码
public static Object newProxyInstance(
        ClassLoader loader,
        Class<?>[] interfaces,
        InvocationHandler h)
}
阶段 做的事 技术点
1️⃣ 接口定义 定义 BaseMapper<T> 泛型接口
2️⃣ 获取代理 getMapper(UserMapper.class) JDK 动态代理
3️⃣ 调用方法 调用 selectById() 反射调用 invoke()
4️⃣ 解析方法 找到对应 SQL 映射 反射+缓存
5️⃣ 执行 SQL 调用 JDBC 执行 SQL SQLSession
6️⃣ 封装结果 将结果封装为 T 类型 泛型+反射
相关推荐
Gogo8161 小时前
BigInt 与 Number 的爱恨情仇,为何大佬都劝你“能用 Number 就别用 BigInt”?
后端
fuquxiaoguang1 小时前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析
毕设源码_廖学姐2 小时前
计算机毕业设计springboot招聘系统网站 基于SpringBoot的在线人才对接平台 SpringBoot驱动的智能求职与招聘服务网
spring boot·后端·课程设计
野犬寒鸦3 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
逍遥德4 小时前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
MX_93594 小时前
Spring的bean工厂后处理器和Bean后处理器
java·后端·spring
程序员泠零澪回家种桔子5 小时前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构
源代码•宸6 小时前
大厂技术岗面试之谈薪资
经验分享·后端·面试·职场和发展·golang·大厂·职级水平的薪资
晚霞的不甘7 小时前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
喵叔哟7 小时前
06-ASPNETCore-WebAPI开发
服务器·后端·c#