/** * 通过 java.lang.reflect.Proxy 实现动态代理基本写法 * * 由于代理类实现代理功能的模式基本相同,所以我们可以写一个通用的方法去代理所有的实现类 * * 实现大致思路(动态编译): * 1、通过String去拼 XxxProxy.java 文件中的代码 * 2、生成文件 * 3、编译 运行 返回结果 * (JVM底层直接拼接字节码来生成结果) * * 实现过程类似于js中的 eval('alert()') 方法 * * 调用: * 1、创建接口、实体类 * 2、创建对应实体类的 Handler 类,重写 invoke 方法,添加前后逻辑 * 3、通过 Proxy.newProxyInstance() 生成代理类 * 4、通过代理类执行方法 */ public class DynamicProxy2 { public static void main(String[] args) { test1(); } public static void test1(){ Aircraft a = new Aircraft(); AircraftHandler ah = new AircraftHandler(a); IFlyable proxy = (IFlyable) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IFlyable.class}, ah); proxy.fly(); } } interface IFlyable{ public void fly(); } class Aircraft implements IFlyable{ @Override public void fly(){ for(int i=1;i<5;i++){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("飞机飞行"+i*100+"米...."); } } } class AircraftHandler implements InvocationHandler{ Aircraft a; public AircraftHandler(Aircraft a){ this.a = a; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object object = null; if("fly".equals(method.getName())){ System.out.println("开始计时...."); System.out.println("[log]开始日志记录"); long start = System.currentTimeMillis(); object = method.invoke(a, args); long end = System.currentTimeMillis(); System.out.println("[log]结束日志记录"); System.out.println("计时结束 共运行"+(end-start)); } return object; } }
/** * 通过 java.lang.reflect.Proxy 实现动态代理 * * 1、定义公共接口 * 2、定义真实对象 继承接口 实现功能 * 3、定义方法处理实现类(TimeHandler/LogHandler) * * 拥有静态代理的优点,同时实现了 实现类 和 代理类 的分离(TimeHandler/LogHandler 可用于任何被代理类) * 接口修改后只需修改具体的实现类,不需要修改代理类 * 比 静态代理 重用性更好,维护性更好 */ public class DynamicProxy3 { public static void main(String[] args) { test1(); System.out.println("-----------------------------"); test2(); System.out.println("-----------------------------"); test3(); System.out.println("-----------------------------"); test4(); } /** * Tank 先进行时间记录,再进行log记录 */ public static void test1(){ Tank t = new Tank(); LogHandler lh = new LogHandler(t); IMoveable logProxy = (IMoveable)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IMoveable.class}, lh); TimeHandler th = new TimeHandler(logProxy); IMoveable timeProxy = (IMoveable)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IMoveable.class}, th); timeProxy.move(); } /** * Tank 先进行log记录,再进行时间记录 */ public static void test2(){ Tank t = new Tank(); TimeHandler th = new TimeHandler(t); IMoveable timeProxy = (IMoveable)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IMoveable.class}, th); LogHandler lh = new LogHandler(timeProxy); IMoveable logProxy = (IMoveable)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IMoveable.class}, lh); logProxy.move(); } /** * Aircraft 先进行时间记录,再进行log记录 */ public static void test3(){ Aircraft a = new Aircraft(); LogHandler lh = new LogHandler(a); IFlyable logProxy = (IFlyable)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IFlyable.class}, lh); TimeHandler th = new TimeHandler(logProxy); IFlyable timeProxy = (IFlyable)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IFlyable.class}, th); timeProxy.fly(); } /** * Aircraft 先进行log记录,再进行时间记录 */ public static void test4(){ Aircraft a = new Aircraft(); TimeHandler th = new TimeHandler(a); IFlyable timeProxy = (IFlyable)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IFlyable.class}, th); LogHandler lh = new LogHandler(timeProxy); IFlyable logProxy = (IFlyable)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{IFlyable.class}, lh); logProxy.fly(); } } /** * 记录时间具体实现 */ class TimeHandler implements InvocationHandler{ Object obj; public TimeHandler(Object o){ this.obj = o; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object object = null; System.out.println("方法"+method.getName()+"开始调用 开始计时...."); long start = System.currentTimeMillis(); object = method.invoke(obj, args); long end = System.currentTimeMillis(); System.out.println("方法"+method.getName()+"调用结束 用时"+(end-start)); return object; } } /** * 记录日志具体实现 */ class LogHandler implements InvocationHandler{ Object obj; public LogHandler(Object o){ this.obj = o; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object object = null; System.out.println("[log]记录"+method.getName()+"方法开始调用日志"); object = method.invoke(obj, args); System.out.println("[log]记录"+method.getName()+"方法结束调用日志"); return object; } }
相关推荐
《设计模式——Java语言中的应用》是一本专为Java开发者深入理解面向对象设计而编写的经典书籍。...无论是初级开发者还是经验丰富的程序员,都应该不断探索和实践设计模式,以提升自己的专业技能。
初级程序员可以学习设计模式的基本概念和应用,高级程序员能够从书中掌握更多高级技巧,而系统分析师可以通过设计模式来解决项目中遇到的复杂问题。 总体而言,设计模式是软件工程领域的宝贵财富,而《JAVA设计模式...
《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础 第2章 简单工厂 第3章 外观模式 第4章 ...
《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础 第2章 简单工厂 第3章 外观模式 第4章 ...
《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础 第2章 简单工厂 第3章 外观模式 第4章 ...
《Java设计模式之禅》是一本深入浅出讲解设计模式的书籍,书...综上所述,本书不仅是一本关于设计模式的入门书,也是对设计模式应用的深入探讨,无论是对于初级开发者、高级程序员,还是系统分析师,都能从中获得价值。
- **初级开发者**:可以学习JavaScript的基础知识和一些简单的设计模式。 - **中级开发者**:可以通过学习设计模式进阶,了解更高级的设计模式和技术细节。 - **高级开发者**:可以深入了解设计模式的应用,以及如何...
《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础 第2章 简单工厂 第3章 外观模式 第4章 ...
代理模式(Proxy)为对象提供一个代理以控制对这个对象的访问;桥接模式(Bridge)将抽象部分与实现部分分离,使它们可以独立变化;组合模式(Composite)将对象组合成树形结构,以表示“部分-整体”的层次结构;...
- **代理模式**:为其他对象提供一个代理,以便控制对这个对象的访问。 - **装饰者模式**:动态地给一个对象添加一些额外的职责,提供比继承更灵活的替代方案。 - **适配器模式**:允许不兼容的接口协同工作。 -...
设计模式是软件工程中解决常见问题的模板或通用解决方案,Java设计模式是这些解决方案在Java语言中的具体实现。《java23种设计模式详细讲解》这本书系统地介绍了23种设计模式,并通过具体的例子来阐释每种模式的应用...
本文讲述的是软件开发领域内设计模式的概念,以及如何将这些模式应用于Java编程中。设计模式是软件工程中,为了解决特定问题而形成的一种通用、可重复使用的解决方案模板。在软件开发中,设计模式为开发者提供了一套...
对于不同级别的程序员,设计模式能够提供不同程度的帮助和指导,从初级程序员的基础编程技能提升,到高级程序员的系统设计和架构,再到系统分析师的项目问题解决,设计模式都能发挥关键作用。 在应用设计模式时,...
《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础 第2章 简单工厂 第3章 外观模式 第4章 ...