现在的位置: 首页 > 综合 > 正文

设计模式之Dynamic Proxy-动态代理

2012年08月14日 ⁄ 综合 ⁄ 共 3318字 ⁄ 字号 评论关闭

 

动态代理(Dynamic Proxy)是JDK5 提供的一种新特性。其特点在于在程序的运行时刻动态的创建出代理类及其对象,而不像我们使用静态代理时必须在编译之前定义好代理类。在运行时刻,框架帮我们动态的创建出一个实现了多个接口的代理类,每个代理类的对象都会和一个InvocationHandler接口的实现类相关联。当我们调用了代理对象所代理的接口中的方法的时候,这个调用的信息会被传递给InvocationHandler的invoke方法。在 invoke方法的参数中可以获取到代理对象、方法对应的Method对象和调用的实际参数(内部是通过反射来实现的)。 invoke方法的返回值被返回给使用者,至于返回什么值可以由自己来定义,这种做法实际上相当于对方法调用进行了AOP拦截。 

 
创建动态代理的步骤如下:
 1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法。
 2. 创建被代理类以及接口
 3. 通过Proxy的静态方法newProxyInstance(ClassLoader loader,  Class<?>[] interfaces, InvocationHandler h)创建一个代理
 4. 通过代理来调用方法(此代理实现了被代理类的接口)
/**
 * DynamicSubject.java
 * dynamicproxy
 *
 * Function: 动态代理类, java.lang.reflect.Proxy 是运行时生成的Class,在生成它的时候你必须传递
 * 一组Interfaces给它(多个接口),然后返回的对象就实现了这些接口,这个Proxy就是一个纯粹的Porxy,
 * 所以我们必须提供一个InvocationHandler,由它来接替
 *
 *   ver     date      		author
 * ──────────────────────────────────
 *   		 2011-6-12 		Leon
 *
 * Copyright (c) 2011, TNT All Rights Reserved.
*/
 
package dynamicproxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
/**
 * ClassName:DynamicSubject
 * Function: TODO ADD FUNCTION
 * 创建动态代理的步骤如下:
 * 1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法。
 * 2. 创建被代理类以及接口
 * 3. 通过Proxy的静态方法newProxyInstance(ClassLoader loader,
 *        Class[] interfaces, InvocationHandler h)创建一个代理
 * 4. 通过代理来调用方法(此代理实现了被代理类的接口)
 *
 *
 * Reason:	 TODO ADD REASON
 *
 * @author   Leon
 * @version
 * @since    Ver 1.1
 * @Date	 2011-6-12
 */
public class DynamicProxy implements InvocationHandler {
 
	private Object sub ; 
 
	public Object getSub() {
		return sub;
	}
	public void setSub(Object sub) {
		this.sub = sub;
	}
	public DynamicProxy(Object obj){
		this.sub=obj;
	}
	//proxy是框架动态生成的代理类
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
 
		// TODO Auto-generated method stub
		Object result = null ;
		System.out.println("before calling: " +  method);
 
		//此处是真正被代理的对象
		result=method.invoke(sub, args);
 
		System.out.println("after calling ...");
 
		return result;
	}
 
	public static void main(String...  args){
 
		RealSubject  realSubject = new RealSubject();
 
		DynamicProxy dynamicProxy = new DynamicProxy(realSubject);
 
//		InvocationHandler invocationHandler = dynamicProxy;
 
		//动态生成一个代理对象,返回的对象既不是RealSubject实例也不是DynamicPorxy的实例,而是动态生成
		//的一个实例 $prxoy0,它实现了realSubject.getClass().getInterfaces()这些接口
		ISubject subject=(ISubject)Proxy.newProxyInstance(dynamicProxy.getClass().getClassLoader(),
				  realSubject.getClass().getInterfaces(),dynamicProxy);
 
		//当调用这一句的时候,$proxy0就会调用上面传入的invocationHandler的invoke方法,所以上面的方法要传入invocationHandler。
		System.out.println("--------------------------Porxy realSubject1 ------------------------------------");
		subject.request();
		String result=subject.test();
		System.out.println("return by test method :" + result);
		System.out.println("--------------------------Proxy realSubject2--------------------------------------");
		dynamicProxy.setSub(new RealSubject2());
		subject.request();
 
		System.out.println("proxy generate by system is :"+subject.getClass());
 
	}
 
}
 
interface ISubject {
	public void request();
    public String test();
}
 
class RealSubject implements ISubject {
 
	@Override
	public void request() {
 
		// TODO Auto-generated method stub
		System.out.println("From  real  subject...request method....");
	}
 
	@Override
	public String test() {
 
		// TODO Auto-generated method stub
		String str ="From real subject.....test  method.....";
		return  str ; 
 
	}
}
 
class RealSubject2 implements ISubject {
 
	@Override
	public void request() {
 
		// TODO Auto-generated method stub
		System.out.println("From  real  subject2...request method....");
	}
 
	@Override
	public String test() {
 
		// TODO Auto-generated method stub
		System.out.println("From real subject2 .....test  method.....");
		return null ;
	}
}

抱歉!评论已关闭.