java设计模式--代理模式(二)

动态代理

java.lang.reflect下Proxy类和InvocationHandler接口可以生成JDK动态代理类或动态代理接口。
java设计模式--代理模式(二)_第1张图片

(1)Interface InvocationHandler 该接口仅定义一个方法
public Object invoke(Object proxy,Method method,Object[] args) //代理类、代理方法、方法参数

(2)Proxy提供两个静态方法
  • static Class getProxyClass(ClassLoader loader, Class... interfaces) 创建动态代理类所对应的Class对象,该代理类将实现interfaces所指定的多个接口。loader指定生成动态代理类的类加载器。
  • static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)直接创建一个动态代理对象,该代理对象的实现类实现了interfaces指定的多个接口。执行代理对象的每个方法时都会被替换执行InvocationHandler的invoke方法。
动态代理的步骤:
(1)创建一个实现InvocationHandler接口的类,它必须实现invoke方法。 (说明:这一点其实类似静态代理中的创建代理类,区别是,可以在不知道委托类接口和委托类的情况下创建)。
(2)创建委托类及其接口。 (说明:这和静态代理中是一样的,这里也可以第一步就创建)
(3)获得代理类实例对象:通过Proxy的静态方法,创建代理类实例对象
        newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
        三个参数理解:需要一个类加载器,委托类和代理类公共的接口,代理类接口的实现

示例:

(1)代理类接口的实现
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class TimeHandler implements InvocationHandler {

	public TimeHandler(Object target) {
		super();
		this.target = target;
	}

	private Object target;
	
	/*
	 * 参数:
	 * proxy  被代理对象
	 * method  被代理对象的方法
	 * args 方法的参数
	 * 
	 * 返回值:
	 * Object  方法的返回值
	 * */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		long starttime = System.currentTimeMillis();
		System.out.println("汽车开始行驶....");
		method.invoke(target);
		long endtime = System.currentTimeMillis();
		System.out.println("汽车结束行驶....  汽车行驶时间:" 
				+ (endtime - starttime) + "毫秒!");
		return null;
	}

}

(2)委托类和接口
接口
public interface Moveable {
	void move();
}
委托类
import java.util.Random;

public class Car implements Moveable {

	@Override
	public void move() {
		//实现开车
		try {
			Thread.sleep(new Random().nextInt(1000));
			System.out.println("汽车行驶中....");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}
(3)获得代理类实例并调用方法
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Test {

	/**
	 * JDK动态代理测试类
	 */
	public static void main(String[] args) {
		Car car = new Car();
		InvocationHandler h = new TimeHandler(car);
		Class cls = car.getClass();
		/**
		 * loader  类加载器
		 * interfaces  实现接口
		 * h InvocationHandler
		 */
		Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(),
												cls.getInterfaces(), h);
		m.move();  //将m看成和委托类一样的实例,调用同名的方法即可
	}
}
结果
汽车开始行驶....
汽车行驶中....
汽车结束行驶....  汽车行驶时间:274毫秒!

小结
动态代理可类比静态代理,动态代理点的好处是在不知道委托类和接口的情况下,仍然可以生成代理类接口。
静态代理步骤:
委托类接口----委托类----代理类
动态代理步骤:
委托类接口----委托类----代理类接口的实现

你可能感兴趣的:(#,设计模式)