`
duolaaqian
  • 浏览: 14112 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

[初级]设计模式--动态代理模式

阅读更多

 

/**
 * 通过 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语言中的应用(pdf)

    《设计模式——Java语言中的应用》是一本专为Java开发者深入理解面向对象设计而编写的经典书籍。...无论是初级开发者还是经验丰富的程序员,都应该不断探索和实践设计模式,以提升自己的专业技能。

    JAVA设计模式-设计模式公司出品

    初级程序员可以学习设计模式的基本概念和应用,高级程序员能够从书中掌握更多高级技巧,而系统分析师可以通过设计模式来解决项目中遇到的复杂问题。 总体而言,设计模式是软件工程领域的宝贵财富,而《JAVA设计模式...

    研磨设计模式-part2

    《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础 第2章 简单工厂 第3章 外观模式 第4章 ...

    研磨设计模式-part4

    《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础 第2章 简单工厂 第3章 外观模式 第4章 ...

    研磨设计模式-part3

    《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础 第2章 简单工厂 第3章 外观模式 第4章 ...

    Java设计模式之禅

    《Java设计模式之禅》是一本深入浅出讲解设计模式的书籍,书...综上所述,本书不仅是一本关于设计模式的入门书,也是对设计模式应用的深入探讨,无论是对于初级开发者、高级程序员,还是系统分析师,都能从中获得价值。

    JS设计模式与开发实践

    - **初级开发者**:可以学习JavaScript的基础知识和一些简单的设计模式。 - **中级开发者**:可以通过学习设计模式进阶,了解更高级的设计模式和技术细节。 - **高级开发者**:可以深入了解设计模式的应用,以及如何...

    研磨设计模式(完整带书签).part2.pdf

    《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础 第2章 简单工厂 第3章 外观模式 第4章 ...

    研磨设计模式PDF

    代理模式(Proxy)为对象提供一个代理以控制对这个对象的访问;桥接模式(Bridge)将抽象部分与实现部分分离,使它们可以独立变化;组合模式(Composite)将对象组合成树形结构,以表示“部分-整体”的层次结构;...

    C/C++设计模式基础教程

    - **代理模式**:为其他对象提供一个代理,以便控制对这个对象的访问。 - **装饰者模式**:动态地给一个对象添加一些额外的职责,提供比继承更灵活的替代方案。 - **适配器模式**:允许不兼容的接口协同工作。 -...

    java23种设计模式详细讲解

    设计模式是软件工程中解决常见问题的模板或通用解决方案,Java设计模式是这些解决方案在Java语言中的具体实现。《java23种设计模式详细讲解》这本书系统地介绍了23种设计模式,并通过具体的例子来阐释每种模式的应用...

    java开发设计模式

    对于不同级别的程序员,设计模式能够提供不同程度的帮助和指导,从初级程序员的基础编程技能提升,到高级程序员的系统设计和架构,再到系统分析师的项目问题解决,设计模式都能发挥关键作用。 在应用设计模式时,...

    研磨设计模式(完整带书签).part1.pdf

    《研磨设计模式》难度为初级到中级,适合与所有开发人员、设计人员或者即将成为开发人员的朋友。也可以作为高效学生深入学习设计模式的参考读物! 第1章 设计模式基础 第2章 简单工厂 第3章 外观模式 第4章 ...

Global site tag (gtag.js) - Google Analytics