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

实现
抽象主题Subject
可以是抽象类或者接口,普通的业务类型定义。
1 2 3
| public interface Subject{ public void request(); }
|
具体主题RealSubject
委托角色或者被代理角色。业务逻辑的具体执行者。
1 2 3 4 5
| public class RealSubject implements Subject{ public void request(){ } }
|
代理主题Proxy
代理类、委托类, 负责对真实角色的调用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
1 2 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一个真实的角色。
这种方式调用者只需要知道代理即可, 不需要知道代理了谁。
普通代理的实现者:
1 2 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(){ } }
|
普通代理的代理者:
1 2 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(); } }
|
强制代理
只有通过真实角色指定的代理类才可以访问。
1 2 3 4
| public interface IGamePlayer{ void killMonster(); public IGamePlayer getProxy(); }
|
1 2 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(){ } }
|
1 2 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类:
1 2 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); } }
|
通知接口与实现
1 2 3 4 5 6 7 8
| public interface IAdvice{ public void exec(); } public class BeforeAdvice implements IAdvice{ public void exec(){ } }
|
动态代理类:
1 2 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:
1 2 3 4
| Subject subject = new RealSubject(); InvocationHandler handler = new MyInvocationHandler(subject); Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler); proxy.killMonster();
|
扩展
1 2 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; } }
|
1 2 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; } }
|
1 2 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; } }
|
1 2 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动态代理详解