JDK动态代理的两个核心分别是InvocationHandler和Proxy。
下面写一个demo:
1.定义一个统一接口
public interface MoveAble {
public void move();
}
2.定义接口的实现
public class Car implements MoveAble {
@Override
public void move() {
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3. 定义proxyHandler
public class TimeHandler implements InvocationHandler {
private Object target;
public TimeHandler(Object target) {
super();
this.target = target;
}
/**
* 参数:<br>
* proxy 被代理的对象<br>
* method 被代理对象的方法 <br>
* params 方法参数
*
* 返回值: Object 方法的返回值
*/
@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
long startTime = System.currentTimeMillis();
System.out.println("汽车开始行驶...");
Object result = null;
try {
Thread.sleep(new Random().nextInt(1000));
result = method.invoke(target, params);
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("汽车行驶结束....,行驶时间:" + (endTime - startTime) + "毫秒...");
return result;
}
}
4.获取代理类
@Test
public void testTimeHandler() {
Car car = new Car();
Class<?> cls = car.getClass();
Class<?>[] interfaces = car.getClass().getInterfaces();
/**
* ClassLoader: 类加载器<br>
* interface[]: 实现接口<br>
* InvocationHandler:处理器<br>
*
*
* 动态代理实现思路<br>
* 1,声明一段源码(动态产生代理)<br>
* 2,编译源码(jdk compiler API),产生新的类(代理类)<br>
* 3,将这个类load到内存当中,产生一个新的对象(代理对象)<br>
* 4,return 代理对象
*/
InvocationHandler invocationHandler = new TimeHandler(car);
MoveAble ma = (MoveAble) Proxy.newProxyInstance(cls.getClassLoader(), interfaces, invocationHandler);
ma.move();
}
总结:jdk的动态代理是基于接口的,如果不是接口实现,则不能用jdk动态代理了
但是,基于接口,并不表示接口一定要有实现类,比如,mybatia中的MapperProxy,最终实现是通过sqlSession实现的。
接口只是一个包装,代理内部的东西,可能就随你自己玩了。