Luckylau's Blog

设计模式之代理模式

​ 代理模式(Proxy Pattern)为指定的类的对象提供代理对象,并通过代理对象对原对象的引用,代理后者执行操作。主要分为静态代理和动态代理;我们以代理服务器为例;

静态代理

我们定义一个海外服务器

1
2
3
public interface HttpServer {
void handleRequest();
}
1
2
3
4
5
public class OverseasHttpServer implements HttpServer {
public void handleRequest() {
System.out.println("海外的HTTP服务器处理请求并返回结果...");
}
}

然后定义一个代理服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class HttpProxy implements HttpServer {
private HttpServer overseasHttpServer;
public HttpProxy(HttpServer overseasHttpServer) {
this.overseasHttpServer = overseasHttpServer;
}
public void handleRequest() {
preRequest();
this.overseasHttpServer.handleRequest();
postRequest();
}
public void preRequest() {
System.out.println("拦截客户端的HTTP请求,发送至海外的代理服务器,由其向海外HTTP服务器发送请求...");
}
public void postRequest() {
System.out.println("海外代理服务其接收海外HTTP服务器反馈的结果,发送回客户端浏览器进行显示...");
}
}
1
2
3
4
5
6
7
HttpServer overseasHttpServer = new OverseasHttpServer();
HttpServer httpServer = new HttpProxy(overseasHttpServer);
httpServer.handleRequest();
//拦截客户端的HTTP请求,发送至海外的代理服务器,由其向海外HTTP服务器发送请求...
//海外的HTTP服务器处理请求并返回结果...
//海外代理服务其接收海外HTTP服务器反馈的结果,发送回客户端浏览器进行显示...

动态代理

​ 对于动态代理来说,需要首先有一个实现InvocationHandler接口的handler,可以简单认为是对被代理的方法的包装。InvocationHandlerinvoke(Object proxy, Method method, Object[] args)方法,proxy指的是动态生成的代理对象,method指的是被代理的操作方法,args指的是被代理方法的参数。

​ Handler有了,那么动态代理的对象怎么生成的呢?Java提供了Proxy工具类newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)来生成代理对象。其中第一个参数loader是类加载器,通常使用被代理类的类加载器即可;第二个参数interfaces是被代理类所实现的接口类数组,可见这种代理方式仍然是基于接口代理的,第三个参数就是我们刚刚准备好的handler。

​ 这个方法会返回一个代理对象,这个对象实现了interfaces指定的接口,因此可以转换类型,然后就可以同静态代理一样的方式来使用了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class HttpProxyHandler implements InvocationHandler {
private HttpServer overseasHttpServer;
public HttpProxyHandler(HttpServer overseasHttpServer) {
this.overseasHttpServer = overseasHttpServer;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
preRequest();
Object o = method.invoke(overseasHttpServer, args);
postRequest();
return o;
}
public void preRequest() {
System.out.println("拦截客户端的HTTP请求,发送至海外的代理服务器,由其向海外HTTP服务器发送请求...");
}
public void postRequest() {
System.out.println("海外代理服务其接收海外HTTP服务器反馈的结果,发送回客户端浏览器进行显示...");
}
}
1
2
3
4
HttpProxyHandler proxy = new HttpProxyHandler(overseasHttpServer);
HttpServer httpProxy = (HttpServer) Proxy.newProxyInstance(proxy.getClass().getClassLoader(),
overseasHttpServer.getClass().getInterfaces(), proxy);
httpProxy.handleRequest();
Luckylau wechat
如果对您有价值,看官可以打赏的!