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

 

/**
 * 通过 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;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值