静态代理仅仅能够代理某一个类,如果有多个类,就需要写多个代理类。
Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:
1)Interface InvocationHandler:该接口中仅定义了一个方法:
public Object invoke(Object obj,Method method,Object[] args)
在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。
这个抽象方法在代理类中动态实现。
2)Proxy:该类即为动态代理类
static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h):
返回代理类的一个实例,返回后的代理类可以当做被代理类使用(可以使用被代理类的在接口中声明的方法)
动态代理实现步骤:
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TimeHandler implements InvocationHandler {
private Object target;
public TimeHandler(Object target) {
super();
this.target = target;
}
/*
* 参数:
* proxy 被代理对象
* method 被代理对象的方法
* args 方法的参数
*
* 返回值:
* Object 方法的返回值
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
long starttime = System.currentTimeMillis();
System.out.println("汽车开始行驶.....");
method.invoke(target);
long endtime = System.currentTimeMillis();
System.out.println("汽车结束行驶.....时间为:" + (endtime - starttime) + "(毫秒)");
return null;
}
}
2.创建被代理的类以及接口
import java.util.Random;
public class Car implements Moveable {
@Override
public void move() {
// TODO Auto-generated method stub
try {
Thread.sleep(new Random().nextInt(1000));
System.out.println("汽车行驶中.....");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.imooc.proxy;
public interface Moveable {
public void move();
}
3.调用Proxy的静态方法,创建一个代理类
newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
public class Test {
/*
* JDK动态代理测试类
*/
public static void main(String[] args) {
Car car = new Car();
InvocationHandler h = new TimeHandler(car);
Class<?> cls = car.getClass();
/*
* loader:类加载器
* interface:实现接口
* h: InvocationHandler
*/
Moveable m = (Moveable)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
m.move();
}
}
4.通过代理调用方法