代理模式
代理模式的应用场景:
- 一个对象不能直接访问另外一个对象的时候,我们可以通过访问该对象的代理对象去访问它。
- 在不修改类的源码的情况下,动态地增强类的方法,便于程序的扩展
- 动态地给接口创建代理对象,动态地实现接口中的方法
- 统一在方法执行之前做前置处理工作,在方法执行之后做后置处理工作,这样可以大大减少代码中的重复代码。这其实就是Spring中的AOP思想
面向对象设计有一个基本原则:开放封闭原则,对扩展开放对修改封闭
改变/增强一个方法,我们又哪些办法可以做到:
- 继承
- 装饰者模式:
- 装饰者和被装饰者要实现相同的接口
- 将被装饰者的对象传入到装饰者中
- 如果不需要增强的方法由被装饰者完成,装饰者只增强方法
- 代理模式:静态代理和动态代理
- 代理模式的组成部分:
- 代理者
- 委托者(被代理者)
- 接口
- 代理模式的特点:
- 代理者和委托者要实现相同的接口
- 将委托者的对象传入到代理者中
- 如果不需要增强的方法由委托者完成,代理者只增强方法
代理模式的分类:
- 静态代理模式:包含委托类、代理类以及统一的接口
- 动态代理模式:包含委托类和统一的接口,不包含代理类,而是使用反射机制在调用的时候动态生成代理对象
一.静态代理
1.Diagrams

2.代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public interface IKindWomen { void happy(); }
public class Jinlian implements IKindWomen { @Override public void happy() { System.out.println("金莲正在happy..."); } }
public class Wangpo implements IKindWomen { private IKindWomen women;
public Wangpo(Jinlian jinlian) { this.women = jinlian; }
@Override public void happy() { System.out.println("open room"); women.happy(); System.out.println("clear room"); } }
@Test public void test(){ Jinlian jinlian = new Jinlian(); Wangpo wangpo = new Wangpo(jinlian); wangpo.happy(); }
|
二.动态代理
1.Diagrams

2.代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| public interface IKindWoman { void happy(); double collect(double money); }
public class Jinlian implements IKindWoman { @Override public void happy() { System.out.println("金莲正在happy..."); }
@Override public double collect(double money) { System.out.println("金莲收款: " + money); return money; } }
@Test public void test(){ Jinlian jinlian = new Jinlian();
Class clazz = jinlian.getClass(); ClassLoader classLoader = clazz.getClassLoader(); Class[] interfaces = clazz.getInterfaces();
IKindWoman proxyInstance = (IKindWoman) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName();
if ("happy".equals(methodName)){ System.out.println("open room"); method.invoke(jinlian,args); System.out.println("clear room"); return null; }
if ("collect".equals(methodName)){ double money = (double) args[0]; System.out.println("扣除中介费 40%: " + money*0.4); return method.invoke(jinlian, money*0.6); }
return method.invoke(jinlian,args); } });
proxyInstance.happy(); double collect = proxyInstance.collect(800); System.out.println(collect);
}
|