-
什么是代理模式
通过代理对象间接控制并访问目标对象的方法; -
补充说明
想到代理模式,容易让人想到AOP思想,Spring中的AOP可以通过动态代理实现;
代理模式有静态代理和动态代理两种;
解耦调用者和被调用者; -
角色
抽象主题,定义一些需要代理的方法
具体主题,实现一些具体逻辑
代理主题,代理和封装具体主题
客户端Main:调用者,通过代理主题访问具体主题 -
例子JAVA实现
这里我们模拟代理上网场景:应用服务器返回信息给代理服务器,代理服务器返回信息给客户端;
抽象主题,服务器接口,有一个response方法,能够返回信息
1 package com.pichen.dp.structuralpattern.proxy;
2 public interface Server {
4 public String response();
5 }
具体主题,某个具体的应用服务器
1 package com.pichen.dp.structuralpattern.proxy;
2 public class ApplicationServer implements Server{
3
4 @Override
5 public String response() {
6 //System.out.println("response from ApplicationServers。");
7 return "response from ApplicationServers";
8 }
9
10 }
静态代理主题角色, 对具体主题的直接引用,直接调用具体主题里的方法
1 package com.pichen.dp.structuralpattern.proxy;
2 public class StaticProxyServer implements Server {
3
4 private ApplicationServer appServer;
5 @Override
6 public String response() {
7 //System.out.println("response from ProxyServer。");
8 if(null == appServer){
9 appServer = new ApplicationServer();
10 }
11 //before , you can do something
12 String str = appServer.response() + "(by ProxyServer, static proxy.)";
13 //after , you can do something
14 return str;
15 }
16
17 }
动态代理InvocationHandler,可以通过它获取动态代理主题角色,代理对象是在运行期间动态生成的;
1 package com.pichen.dp.structuralpattern.proxy;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5 import java.lang.reflect.Proxy;
6
7 public class DynamicProxyServerHandler implements InvocationHandler{
8
9 private Server appServer;
10
11 public DynamicProxyServerHandler(Server appServer) {
12 this.appServer = appServer;
13 }
14
15 //获取动态代理对象
16 public Object getProxyyServer(){
17 return Proxy.newProxyInstance(appServer.getClass().getClassLoader(),
18 appServer.getClass().getInterfaces(), this);
19 }
20
21 @Override
22 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
23 //before , you can do something
24 Object str = method.invoke(appServer, args);
25 //after , you can do something
26 return str.toString() + "(by ProxyServer, dynamic proxy.)";
27 }
28
29 }
客户端,Main类,通过代理服务器获取应用服务器的返回信息
1 package com.pichen.dp.structuralpattern.proxy;
2
3 public class Main {
4 public static void main(String[] args) {
5 //静态代理
6 Server staticProxyServer = new StaticProxyServer();
7 System.out.println(staticProxyServer.response());
8
9 //动态代理
10 DynamicProxyServerHandler dpshandler = new DynamicProxyServerHandler(new ApplicationServer());
11 Server dynamicProxyServer = (Server) dpshandler.getProxyyServer();
12 System.out.println(dynamicProxyServer.response());
13 }
14 }
结果打印
response from ApplicationServers(by ProxyServer, static proxy.)
response from ApplicationServers(by ProxyServer, dynamic proxy.)
代理模式(Proxy)
代理模式就是多一个代理类出来,替原对象进行一些操作:
public interface Sourceable {
public void method();
}
public class Source implements Sourceable {
@Override
public void method() {
System.out.println("the original method!");
}
}
public class Proxy implements Sourceable {
private Source source;
public Proxy(){
super();
this.source = new Source();
}
@Override
public void method() {
before();
source.method();
atfer();
}
private void atfer() {
System.out.println("after proxy!");
}
private void before() {
System.out.println("before proxy!");
}
}
测试类:
public class ProxyTest {
public static void main(String[] args) {
Sourceable source = new Proxy();
source.method();
}
}
输出:
before proxy!
the original method!
after proxy!