Design Pattern—— Dynamic Proxy Pattern 动态代理模式

动态代理模式 Dynamic Proxy Pattern

个人总结:相比较与静态代理模式,动态模式更加灵活。 ,可以对不同的对象进行代理,。对不同的方法进行代理。通过比较会发现,静态代理的做法是将代理与被代理的对象写死,不灵活。而动态代理则通过实现InvocationHandler的invoke方法,用发射机制灵活地代理多种实现相同接口的对象, 动态代理是框架Spring的基石。

下面以一个简单例子说明:

Step One:

创建被代理的类和接口。即是创建真实角色和抽象角色。 真实角色实现抽象角色。

package com.master.proxy;

//接口,抽象角色
public interface AbstractProxy { 

	public abstract void getPhone();
	
	public abstract void getMoney();
	
}

package com.master.proxy;

 // 被代理的类,真实角色,它实现抽象角色AbstractProxy接口
public class RealSub implements AbstractProxy {

	@Override
	public void getPhone() { // method 1
		// TODO Auto-generated method stub
		System.out.println("cost 500 RMB");
		System.out.println("that's the end");
	}
	@Override
	public void getMoney() { // method 2
		System.out.println("say hello.And this is getMoney method");
	}
}


Step Two:

创建一个实现了InvocationHandler接口的实现类。它必须实现invoke方法。

package com.master.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyHandle implements InvocationHandler {

	private Object proxyy;

	public ProxyHandle(Object obj) {  //接收传入的被代理的对象
		this.proxyy = obj;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {

		System.out.println("before: " + method); // 打印 调用了哪个对象

		method.invoke(proxyy, args);  

		System.out.println("after: " + method);

		return null;
	}
}

Step Three:

通过Proxy的静态方法来创建一个运行时的代理对象!  并通过该代理对象调用方法。

Proxy.newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
注意,这个对象也是被宣称实现了抽象角色AbstractProxy接口。仔细分析下JDk中的newProxyInstance函数会发现第二个参数接收的是 interfaces ,也就是创建的新的proxy代理对象也是实现了这些接口的,注意是Class<>类型数组,可以有多个接口。

package com.master.proxy;

import java.lang.reflect.Proxy;

public class Client {

	public static void main(String[] args) {

		RealSub realSub = new RealSub();

		ProxyHandle proxyHandle = new ProxyHandle(realSub);

		AbstractProxy obj = (AbstractProxy) Proxy.newProxyInstance(
				ProxyHandle.class.getClassLoader(), realSub.getClass()
						.getInterfaces(), proxyHandle);// obj是运行时动态生成的。
		// getInterfaces宣称实现了哪几种interfaces,则生成实现了哪几接口的代理对象(这里是宣称AbstractProxy接口) 返回值强制为那几种接口的任何一种 

		obj.getPhone();  // 新产生的代理对象obj调用getPhone方法,实际是交给proxyHandler处理。obj是代理角色!
		obj.getMoney();

	}
}

这样,通过newProxyInstance方法new出来的新的代理对象obj 也自热而然地实现了了抽象角色AbstractProxy接口。


输出:

before: public abstract void com.master.proxy.AbstractProxy.getPhone()
cost 500 RMB
that's the end
after: public abstract void com.master.proxy.AbstractProxy.getPhone()
before: public abstract void com.master.proxy.AbstractProxy.getMoney()
say hello.And this is getMoney method
after: public abstract void com.master.proxy.AbstractProxy.getMoney()


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值