代理模式
代理模式也叫委托模式,许多其他的模式如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了代理模式。
在日常应用中,代理模式可以提供非常好的访问控制。
定义
为其他对象提供一种代理以控制这个对象的访问。
比如,我们的DB的访问权限不能直接公开,一般会公开一个接口来提供对这些数据。

实现
抽象主题Subject
可以是抽象类或者接口,普通的业务类型定义。
| 12
 3
 
 | public interface Subject{public void request();
 }
 
 | 
具体主题RealSubject
委托角色或者被代理角色。业务逻辑的具体执行者。
| 12
 3
 4
 5
 
 | public class RealSubject implements Subject{public void request(){
 
 }
 }
 
 | 
代理主题Proxy
代理类、委托类, 负责对真实角色的调用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | public class Proxy implements Subject{private Subject subject = null;
 
 public Proxy(){
 this.subject = new Proxy();
 }
 
 public Proxy(Subject subject){
 this.subject = subject;
 }
 
 public void request(){
 this.before();
 this.subject.request();
 this.after();
 }
 
 private void before(){
 
 }
 private void after(){
 
 }
 }
 
 | 
应用
优点
- 职责清晰
 真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事物,通过后期的代理完成一件事物,附带的结果就是编程简洁清晰。
- 扩展性好
 具体主题角色是随时都会发生变化的,只要它实现了接口,代理类可以在不做任何修改的情况下使用。
- 智能化
 用于动态代理。
扩展
普通代理
客户端只能访问代理角色,而不能访问真实角色。屏蔽了真实角色的变更对高层模块的影响。该模式适合对扩展性要求较高的场合。一般通过编程规范类约束来禁止new一个真实的角色。
这种方式调用者只需要知道代理即可, 不需要知道代理了谁。
普通代理的实现者:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | public class GamePlayer implements IGamePlayer{private String name = "";
 public GamePlayer(IGamePlayer _gamePlayer, String _name)throws Exception{
 if(_gamePlayer == null || !(_gamePlayer instanceof GameProxy)){
 throw new Exception("Create Not Allowed!");
 }
 this.name = _name;
 }
 public void killMonster(){
 
 }
 }
 
 | 
普通代理的代理者:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | public class GamePlayerProxy implements IGamePlayer{private IGamePlayer gamePlayer = null;
 public GamePlayerProxy(String name){
 try{
 gamePlayer = new GamePlayer(this,name);
 }catch(Exception e){
 
 }
 }
 
 public void killMonster(){
 this.gamePlayer.killMonster();
 }
 }
 
 | 
强制代理
只有通过真实角色指定的代理类才可以访问。
| 12
 3
 4
 
 | public interface IGamePlayer{void killMonster();
 public IGamePlayer getProxy();
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | public class GamePlayer implements IGamePlayer{private String name = "";
 private IGamePlayer proxy = null;
 public GamePlayer(String _name){
 this.name = _name;
 this.proxy = new GamepPlayerProxy(this);
 }
 public IGamePlayer getProxy(){
 return this.proxy;
 }
 public void killMonster(){
 
 }
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | public class GamePlayerProxy implements IGamePlayer{private IGamePlayer gamePlayer = null;
 public GamePlayerProxy(IGamePlayer _gamePlayer){
 this.gamePlayer = _gamePlayer;
 }
 public void killMonster(){
 this.gamePlayer.killMonster();
 }
 }
 
 | 
动态代理
在实现阶段不需要关心代理谁, 在运行阶段才指定代理哪个对象。
通过InvocationHandler接口,所有方法都由该Handler来接管实际的业务处理。
在不改变已有代码结构的情况下增强或者控制对象的行为。
动态代理Handler类:
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | public class MyInvocationHandler implements InvocationHandler{private Object target = null;
 public MyInvocationHandler(Object _obj){
 this.target = _obj;
 }
 public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{
 return method.invoke(this.target, args);
 }
 }
 
 | 
通知接口与实现
| 12
 3
 4
 5
 6
 7
 8
 
 | public interface IAdvice{public void exec();
 }
 public class BeforeAdvice implements IAdvice{
 public void exec(){
 
 }
 }
 
 | 
动态代理类:
| 12
 3
 4
 5
 6
 7
 8
 
 | public class DynamicProxy<T>{public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h){
 if(condition){
 (new BeforeAdvice()).exec();
 }
 return (T)Proxy.newProxyInstance(loader, interface, h);
 }
 }
 
 | 
Client:
| 12
 3
 4
 
 | Subject subject = new RealSubject();InvocationHandler handler = new MyInvocationHandler(subject);
 Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler);
 proxy.killMonster();
 
 | 
扩展
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | public class LogInterceptor implements MethodInterceptor {
 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
 
 System.out.println("Before Interceptor1");
 Object result = methodProxy.invokeSuper(o, objects);
 System.out.println("After Interceptor1");
 return result;
 }
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | public class LogInterceptor2 implements MethodInterceptor {
 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
 
 System.out.println("Before Interceptor2");
 Object result = methodProxy.invokeSuper(o, objects);
 System.out.println("After Interceptor2");
 return result;
 }
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | public class LogCallBackFilter implements CallbackFilter {
 public int accept(Method method) {
 if ("upgrade".equals(method.getName())){
 System.out.println("Upgrade Filter");
 return 0;
 }
 
 System.out.println("Kill Monster Filter");
 return 1;
 }
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | LogInterceptor logInterceptor = new LogInterceptor();
 LogInterceptor2 logInterceptor2 = new LogInterceptor2();
 
 Enhancer enhancer = new Enhancer();
 enhancer.setSuperclass(GamePlayer.class);
 enhancer.setCallbacks(new Callback[]{logInterceptor,logInterceptor2, NoOp.INSTANCE});
 
 enhancer.setCallbackFilter(new LogCallBackFilter());
 
 IGamePlayer gamePlayer = (IGamePlayer)enhancer.create(new Class[]{String.class}, new Object[]{"Lisi"});
 
 gamePlayer.killMonster();
 gamePlayer.upgrade();
 
 | 
扩展阅读
cglib动态代理、asm学习笔记
Java动态代理详解