Java动态代理实战:手把手教你实现明星经纪人模式

发布时间:2026-01-18 10:38

Java动态代理实战:手把手教你实现明星经纪人模式

在日常开发中,我们经常遇到这样的场景:某个对象需要专注于核心业务,而一些非核心的辅助工作(如前置准备、后续处理)希望交给其他对象来完成。这时候,代理模式就派上了用场。今天我们就通过一个「明星+经纪人」的生动案例,带你吃透Java动态代理的实现原理和使用场景。

一、场景引入:为什么明星需要经纪人?

想象一下:明星的核心工作是唱歌、跳舞等表演,但在表演前需要准备场地、收取报酬,这些杂事如果让明星自己处理,会分散其精力。这时候就需要一个「经纪人」(代理对象),帮明星处理这些辅助工作,明星只需要专注于表演本身。

对应到Java开发中:

明星 = 目标对象(专注核心业务) 经纪人 = 代理对象(处理辅助工作,拦截核心方法) 唱歌/跳舞 = 目标方法(需要被代理的核心行为)

这就是代理模式的核心思想:职责分离、功能增强,在不修改目标对象代码的前提下,为其添加额外功能。

二、动态代理 vs 静态代理

在Java中,代理分为「静态代理」和「动态代理」:

静态代理:需要手动为每个目标类编写代理类,实现目标接口,代码冗余,灵活性差。 动态代理:无需手动编写代理类,在运行时动态生成代理对象,只需指定目标接口和增强逻辑,灵活高效。

本文重点讲解JDK自带的动态代理(基于接口实现),也是开发中最常用的动态代理方式。

三、代码实现:一步步搭建明星经纪人系统

1. 项目结构

先看一下整体项目结构,清晰明了:

com.wmh.demo4proxy StarService.java // 明星行为接口(定义需要代理的方法) Star.java // 明星类(目标对象,实现核心业务) ProxyUtil.java // 代理工具类(创建动态代理对象) Test.java // 测试类(验证代理效果) 2. 第一步:定义行为接口(StarService)

动态代理基于接口实现,我们首先定义明星的核心行为接口,明确需要被代理的方法:

package com.wmh.demo4proxy; // 明星行为接口:定义代理需要实现的方法 public interface StarService { // 唱歌方法(带参数) void sing(String name); // 跳舞方法(有返回值) String dance(); } 3. 第二步:实现目标对象(Star类)

明星类实现StarService接口,专注于核心业务逻辑(唱歌、跳舞),不关心任何辅助工作:

package com.wmh.demo4proxy; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; // Lombok注解:自动生成getter、setter、构造方法,简化代码 @Data @AllArgsConstructor @NoArgsConstructor public class Star implements StarService { private String name; // 明星姓名 // 核心业务:唱歌 @Override public void sing(String name) { System.out.println(this.name + "表演唱歌" + name); } // 核心业务:跳舞 @Override public String dance() { System.out.println(this.name + "表演跳舞:魅力四射!"); return "谢谢!谢谢! "; } } 4. 第三步:编写代理工具类(ProxyUtil)

这是动态代理的核心!我们通过java.lang.reflect.Proxy类创建代理对象,通过InvocationHandler接口定义代理逻辑(辅助工作)。

package com.wmh.demo4proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 代理工具类 = 经纪人公司:负责创建代理对象,处理辅助工作 */ public class ProxyUtil { // 为明星创建代理对象(参数:目标对象Star,返回:代理对象StarService) public static StarService createProxy(Star star) { /** * Proxy.newProxyInstance():生成代理对象的核心方法,3个关键参数 * 参数1:类加载器(用当前工具类的类加载器加载代理类) * 参数2:目标对象实现的接口(代理类需要实现和目标对象相同的接口,保证方法一致) * 参数3:InvocationHandler(代理逻辑处理器,拦截目标方法并添加额外功能) */ StarService proxy = (StarService) Proxy.newProxyInstance( ProxyUtil.class.getClassLoader(), // 类加载器 star.getClass().getInterfaces(), // 目标对象的接口 new InvocationHandler() { // 代理逻辑 /** * invoke():代理对象的方法被调用时,会自动触发该方法 * 参数1:proxy:代理对象本身(一般不用) * 参数2:method:当前被调用的目标方法(如sing、dance) * 参数3:args:当前方法的参数(如sing的歌曲名) * 返回值:目标方法的返回值(需返回给调用者) */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 1. 代理的辅助工作(前置增强) String methodName = method.getName(); // 获取当前调用的方法名 if ("sing".equals(methodName)) { System.out.println("准备话筒,收钱20万!"); } else if ("dance".equals(methodName)) { System.out.println("准备场地,收钱100万!"); } // 2. 调用目标对象的核心方法(明星真正干活) Object result = method.invoke(star, args); // 反射调用目标方法 return result; // 返回目标方法的结果 } } ); return proxy; } } 5. 第四步:测试代理效果(Test类)

创建明星对象和代理对象,调用代理方法,验证是否触发代理逻辑:

package com.wmh.demo4proxy; public class Test { public static void main(String[] args) { // 1. 创建目标对象:明星张三 Star star = new Star("张三"); // 2. 创建代理对象:为张三分配经纪人 StarService proxy = ProxyUtil.createProxy(star); // 3. 调用代理对象的方法(间接调用明星的核心方法) proxy.sing("《浪漫手机》"); System.out.println(proxy.dance()); } } 6. 运行结果

准备话筒,收钱20万! 张三表演唱歌《浪漫手机》 准备场地,收钱100万! 张三表演跳舞:魅力四射! 谢谢!谢谢!

完美!代理对象成功拦截了目标方法,先执行经纪人的辅助工作(收钱、准备),再调用明星的核心业务,最后返回结果。

四、动态代理核心原理拆解

1. 核心类和接口 Proxy类:JDK提供的代理工厂类,newProxyInstance()方法在运行时动态生成代理类的字节码,并创建代理对象。 InvocationHandler接口:代理逻辑的核心,invoke()方法会在代理对象的方法被调用时自动触发,负责拦截目标方法并添加增强逻辑。 2. 执行流程 调用代理对象的sing()或dance()方法; JVM自动将调用转发给InvocationHandler的invoke()方法; 在invoke()中执行前置增强逻辑(经纪人工作); 通过反射method.invoke(star, args)调用目标对象的核心方法; 返回目标方法的结果给调用者。 3. 关键注意点 动态代理只能代理接口,不能直接代理类(如果需要代理类,可使用CGLIB框架); 代理对象和目标对象实现了相同的接口,因此调用者可以无缝切换使用代理对象或目标对象; 增强逻辑与核心业务解耦,无需修改目标对象代码,符合「开闭原则」。

五、动态代理的实际应用场景

除了案例中的「经纪人模式」,动态代理在Java开发中还有很多经典应用:

日志记录:拦截方法调用,记录方法入参、出参、执行时间; 权限控制:调用方法前验证用户权限,无权限则拦截; 事务管理:Spring框架中,通过动态代理实现声明式事务(@Transactional); 缓存增强:方法调用前先查询缓存,无缓存再执行方法并缓存结果; 性能监控:统计方法执行耗时,分析系统瓶颈。

六、为什么是"动态"代理?

"动态"体现在两个关键点:

动态生成:在运行时(不是编译时)生成代理类的字节码,不需要提前编写代理类。 动态绑定:可以在运行时指定目标对象和增强逻辑,更加灵活。

七、总结

本文通过「明星+经纪人」的生动案例,带你掌握了Java JDK动态代理的实现方式和核心原理:

动态代理的核心是「运行时生成代理对象」,无需手动编写代理类; 核心依赖Proxy类和InvocationHandler接口,通过反射实现方法拦截; 优势是解耦、灵活、可复用,能在不修改目标对象的前提下增强功能。

如果你的项目中需要为多个对象添加相同的辅助功能(如日志、权限),动态代理绝对是高效的解决方案。赶紧把这个案例跑起来,动手实践一下吧!

重要提示:动态代理是Spring AOP(面向切面编程)的基础,理解了动态代理,你就能更好地理解Spring框架的底层实现。

网址:Java动态代理实战:手把手教你实现明星经纪人模式 https://mxgxt.com/news/view/1956005

相关内容

静态代理:用明星与经纪人的故事理解代理模式
Java设计模式之代理模式——经纪人的工作
代码界的「明星经纪人」:代理模式的替身艺术
静态代理:用明星与经纪人的故事理解代理模式一、故事解说:明星的经纪人如何工作 假设你是一位顶流明星,每天有很多事务: 你
【Java】大明星类会唱跳rap,如何使用动态代理为其增强功能,扩展类的行为今天学习Java的动态代理,我们来探讨动态代
Java 代理从 0 到彻底搞懂
StarCCM利用Java宏实现批处置
动态代理与反射1.动态代理 为什么需要代理? 假设你是个明星(BigStar),工作是唱歌、跳舞。但每次演出前,经纪人(
JDK动态代理 vs CGLIB:一场经纪人之战,谁才是你的最佳选择?咱今儿个来聊聊JDK动态代理和CGLIB代理,保证
动态代理:1 个经纪人如何代理 N 个明星

随便看看