您的位置:首页 > 编程语言 > Java开发

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

2017-05-19 15:31 369 查看

动态代理

java.lang.reflect下Proxy类和InvocationHandler接口可以生成JDK动态代理类或动态代理接口。



(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毫秒!


小结

动态代理可类比静态代理,动态代理点的好处是在不知道委托类和接口的情况下,仍然可以生成代理类接口。
静态代理步骤:
委托类接口----委托类----代理类
动态代理步骤:
委托类接口----委托类----代理类接口的实现
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java java设计模式