1、介绍
在讲解动态代理之前,我们要弄懂一个概念:
什么是代理模式?
可以看成是对调用目标的一个封装,我们对目标代码的调用不是解法发生的,而是通过代理完成的,这在一定程度上解决了调用者和实现者这之间的耦合。
什么意思呢?
举个例子吧,比如说我们要租房,最省事的办法就是找个中介,你只要告诉他你需要什么型号的房,然后啥都不用管,他会帮你找房,非常省事,他会帮你找合适的房东,你最后只要交钱就行了,那么在这里,房东就是调用目标,而中介就是我们所说的代理者,你可以根据代理者而间接达到你租房的目的。那么这个场景用代码怎么实现呢?
public interface Room {
void rent();
}
class RoomImpl implements Room{
@Override
public void rent() {
System.out.println("三室一厅");
}
}
class RoomProxy implements Room{
private Room room;
public RoomProxy(Room room){
this.room = room;
}
@Override
public void rent() {
System.out.println("租房前准备");
room.rent();
System.out.println("租完了");
}
}
public class Client {
public static void main(String[] args) {
RoomImpl impl = new RoomImpl();
RoomProxy proxy = new RoomProxy(impl);
proxy.rent();
}
}
image.png
这样你就应该有个比较直观的感觉了吧?那么你想一下这样写有没有什么不足?想一想,如果我一个类中所代理的方法有很多,这样是不是要无形之中增加很多方法?还有,像刚刚这个例子,每次租房前都要准备合同啊等各种必要工作,那是不是会产生代码冗余呢?而且维护起来也不方便,那么有什么办法能解决这样一个问题呢?
哎!这时候动态代理就出来了,利用反射机制,可以使得相应的调用操作动态完成。看运行时调用哪个就代理哪个,这样就只需要一个方法就可以了,这样是不是就实现了复用了呢?
提供一下代码瞧瞧吧!这样比较直观:
public class DynaProxy {
public static void main(String[] args) {
Work work = new WorkImpl();
MyInvocationHandle handle = new MyInvocationHandle(work);
Work proxy = (Work) Proxy.newProxyInstance(WorkImpl.class.getClassLoader(),WorkImpl.class.getInterfaces(),
handle);
proxy.dowork();
}
}
interface Work{
void dowork();
}
class WorkImpl implements Work{
@Override
public void dowork() {
System.out.println("do work");
}
}
class MyInvocationHandle implements InvocationHandler{
private Object object;//被代理对象
public MyInvocationHandle(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("befor");
Object result = method.invoke(object,args);
System.out.println("after");
return result;
}
}
首先我们实现InvocationHandler,以接口为纽带构建Proxy代理对象,通过对代理对象的调用间接实现对目标对象的调用
newProxyInstance返回的是一个实现了dowork接口的一个代理类。
网友评论