读不懂的定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。
定义解释:举一个例子,比如生活中租房: 我使用“x如”app,这个房源,我只需要找这个“x如”中介,看房,交钱我不用去找房东,这个中介帮房东把这些事情都做好了。
用代码来解释就是:
(租房子这个动作)
1 public interface Rent { 2 public void rent(); 3 }
(房东有房子出租)
房东类:
1 public class Host implements Rent{ 2 public void rent() 3 { 4 System.out.println("我有房子出租."); 5 } 6 7 }
(中介帮房东挂房源)
中介类:
1 public class Proxy implements Rent{ 2 private Host host; 3 4 public Proxy() { 5 } 6 7 public Proxy(Host host) { 8 this.host = host; 9 } 10 11 @Override 12 public void rent() { 13 host.rent(); 14 inspectHouse(); 15 signContract(); 16 } 17 public void inspectHouse() 18 { 19 System.out.println("找中介看房子."); 20 } 21 public void signContract() 22 { 23 System.out.println("找中介签合同"); 24 } 25 }
(我去租房)
客户类:
1 public class Client { 2 public static void main(String[] args) { 3 Host host = new Host(); 4 Proxy proxy = new Proxy(host); 5 proxy.rent(); 6 } 7 }
我只需要找租房中介就可以租到想要的房子,我也不知道这个房子是谁的房子,我只需要交钱入住就行。
解释:例如,我要租房,但是我找不到房源,所以我就只能去找中介。 而中介和房东都有 租房这一相同接口。他们都是向外租房的。
这里就和面向切面编程有一点联系了,一个已经上线的程序,我想修改程序中某个方法的功能,这时候如果直接修改源程序代码,就会产生导致程序崩溃的可能性,这时候,我们可以通过一个代理类来完成这些方法。再像方法中加入我要增加的新功能。
我们要实现增删改查功能,首先定义一个接口。
1 public interface Service { 2 public void add(); 3 public void delete(); 4 public void update(); 5 public void query(); 6 }
定义一个实现增删改查接口的 ServiceImpl类。
1 public class ServiceImpl implements Service{ 2 public void add() 3 { 4 System.out.println("增加用户"); 5 } 6 public void delete() 7 { 8 System.out.println("删除用户"); 9 } 10 public void update() 11 { 12 System.out.println("更新用户"); 13 } 14 public void query() 15 { 16 System.out.println("查询用户"); 17 } 18 19 }
我们项目已经上线了,这时候,我要给增删改查方法中加入日志功能。此时就不能再在源代码的基础上进行修改了。这样有可能导致程序崩溃。
这时候建立一个代理类。
1 public class ServiceProxy implements Service { 2 private ServiceImpl service; 3 4 public void setService(ServiceImpl service) { 5 this.service = service; 6 } 7 8 @Override 9 public void add() { 10 log("add"); 11 service.add(); 12 } 13 14 @Override 15 public void delete() { 16 log("delete"); 17 service.delete(); 18 } 19 20 @Override 21 public void update(){ 22 log("update"); 23 service.update(); 24 } 25 26 @Override 27 public void query() { 28 log("query"); 29 service.query(); 30 } 31 //日志方法 32 public void log(String msg) 33 { 34 System.out.println("使用了"+msg+"方法"); 35 } 36 }
我们就可以通过用实现代理类的方法从而达到我们预期的目标。
1 public class Client { 2 public static void main(String[] args) { 3 ServiceImpl service = new ServiceImpl(); 4 ServiceProxy proxy = new ServiceProxy(); 5 proxy.setService(service); 6 7 proxy.add(); 8 } 9 }
这时候输出结果就为:
增加了一行日志输出效果。这就是所谓的 “开闭原则,增加功能。“
动态代理类:在程序运行时,通过反射机制动态生成。
动态代理类通常代理接口下的所有类。
动态代理事先不知道要代理的是什么,只有在运行的时候才能确定。
动态代理的调用处理程序必须事先InvocationHandler接口,及使用Proxy类中的newProxyInstance方法动态的创建代理类。
Java动态代理只能代理接口,要代理类需要使用第三方的CLIGB等类库。
该文章通过代码比较详细的介绍了动态代理。
作者写的非常详细,可以帮助理解动态代理的机制。
https://blog.csdn.net/zs520ct/article/details/79593196
动态代理在后续AOP中,有很多的知识点对应,所以需要先理解深刻。再进行AOP学习。
原文:https://www.cnblogs.com/Yddd-G/p/12556202.html