本文源码:GitHub·点这里 || GitEE·点这里
一、生活场景
1、场景描述
在电商高速发展的今天,快递的数量十分庞大,甚至出现了快递代理行业,简单的说就是快递的主人没有时间收快递,会指定一个快递的代收点,比如快递柜,快递驿站等,然后等有时间的时候再过去取,下面使用代码对这个场景进行简单的描述。
2、场景图解

3、源码实现
1public class C01_InScene { 2 public static void main(String[] args) { 3 /*自己收快递的测试方式*/ 4 GetExpress getExpress = new GetExpress(); 5 getExpress.sureInfo(); 6 getExpress.signName("张三"); 7 /*代收快递的测试方式*/ 8 ExpressAct getUser = new GetExpress(); 9 ExpressAct getProxy = new ProxyExpress(getUser); 10 getProxy.sureInfo(); 11 getProxy.signName("李四"); 12 } 13} 14/** 15 * 接收一个快递的动作接口:确认信息,签名 16 */ 17interface ExpressAct{ 18 void sureInfo(); 19 void signName(String name); 20} 21/** 22 * 定义一个类接收快递:自己去拿快递 23 */ 24class GetExpress implements ExpressAct{ 25 @Override 26 public void sureInfo() { 27 System.out.println("请确认你的个人信息!"); 28 } 29 @Override 30 public void signName(String name) { 31 System.out.println("你的名字是:"+name); 32 } 33} 34/** 35 * 定义一个类接收快递:找人代领快递 36 */ 37class ProxyExpress implements ExpressAct{ 38 private ExpressAct expressAct=null; 39 public ProxyExpress(ExpressAct expressAct){ 40 this.expressAct = expressAct; 41 } 42 @Override 43 public void sureInfo() { 44 this.expressAct.sureInfo(); 45 } 46 @Override 47 public void signName(String name) { 48 this.expressAct.signName(name); 49 } 50}
二、代理模式
1、概念描述
代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。所谓代理,就是一个对象代表另一个对象执行相应的动作程序。而代理对象可以在客户端和目标对象之间起到中介的作用。
2、模式图解

3、核心角色
- 抽象对象角色
声明目标对象和代理对象的共同接口。
- 目标对象角色
定义了代理对象所代表的目标对象。
- 代理对象角色
代理对象内部含有目标对象的引用,可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象,AOP编程就是基于这个思想。
4、源码实现
1public class C02_Proxy { 2 public static void main(String[] args) { 3 AbstractObject object = new ProxyObject(); 4 object.operation(); 5 } 6} 7/** 8 * 抽象对象角色 9 */ 10abstract class AbstractObject{ 11 public abstract void operation(); 12} 13/** 14 * 目标对象角色 15 */ 16class TargetObject extends AbstractObject{ 17 @Override 18 public void operation() { 19 System.out.println("Target Method Run..."); 20 } 21} 22/** 23 * 代理对象角色 24 */ 25class ProxyObject extends AbstractObject{ 26 TargetObject targetObject = new TargetObject(); 27 @Override 28 public void operation() { 29 System.out.println("Method Before..."); 30 targetObject.operation(); 31 System.out.println("Method After..."); 32 } 33}
三、JDK动态代理
基于JDK动态代理方式实现AOP切面编程。
1、代码实现
1public class C03_JdkProxy { 2 public static void main(String[] args) { 3 BookService bookService = BookAopProxyFactory.createService() ; 4 System.out.println(bookService.getBook()); 5 } 6} 7class BookAspect { 8 public void before (){ 9 System.out.println("Method Before ..."); 10 } 11 public void after (){ 12 System.out.println("Method After ..."); 13 } 14} 15interface BookService { 16 String getBook () ; 17} 18class BookServiceImpl implements BookService { 19 @Override 20 public String getBook() { 21 System.out.println("目标方法【getBook】被执行"); 22 return "高性能MySQL"; 23 } 24} 25class BookAopProxyFactory { 26 public static BookService createService() { 27 // 目标类 28 final BookService bookService = new BookServiceImpl() ; 29 // 切面类 30 final BookAspect bookAspect = new BookAspect(); 31 /* 32 * 代理类:将目标类(切入点)和 切面类(通知) 结合 33 */ 34 BookService proxyBookService = (BookService) Proxy.newProxyInstance( 35 BookAopProxyFactory.class.getClassLoader(), 36 bookService.getClass().getInterfaces(), 37 new InvocationHandler() { 38 public Object invoke(Object proxy, Method method, 39 Object[] args) throws Throwable { 40 // 前执行 41 bookAspect.before(); 42 // 执行目标类的方法 43 Object obj = method.invoke(bookService, args); 44 // 后执行 45 bookAspect.after(); 46 return obj; 47 } 48 }); 49 return proxyBookService ; 50 } 51}
四、几种常见代理
- 防火墙代理
内网通过代理穿透防火墙,实现对公网的访问。
- 缓存代理
为了缓解网站并发压力,在请求数据库资源时,先取缓存中代理的数据,如果缓存未命中,再到数据库取数据,然后缓存取到的数据。
- 远程代理
远程对象的本地代理对象,通过它可以把远程对象当本地对象调用 。远程代理通过网络和调用的远程对象进行信息交互 。
- 同步代理
主要使用在多线程编程中,完成多线程间同步工作。
五、源代码地址
1GitHub·地址 2https://github.com/cicadasmile/model-arithmetic-parent 3GitEE·地址 4https://gitee.com/cicadasmile/model-arithmetic-parent
