代理模式--原理及实现

代理模式在Java中用于在目标对象基础上增加额外功能,包括静态代理和动态代理。静态代理通过编译时创建代理类实现,而动态代理如JDK动态代理和CGLib则能在运行时动态生成代理类。JDK动态代理通过实现InvocationHandler接口,利用Proxy类创建代理对象,适用于接口代理。CGLib则基于ASM库,通过字节码技术在运行时生成目标类的子类以实现动态代理,适用于类代理。动态代理在处理大量接口时更灵活,降低了代码冗余。
摘要由CSDN通过智能技术生成

简介

Java编程的目标是实现现实不能完成的,优化现实能够完成的,是一种虚拟技术。生活中的方方面面都可以虚拟到代码中。代理模式所讲的就是现实生活中的这么一个概念:中介

代理模式的定义:给某一个对象提供一个代理,并由代理对象控制对原对象的引用。

代理模式包含如下角色:

ISubject:抽象主题角色,是一个接口。该接口是对象和它的代理共用的接口。

RealSubject:真实主题角色,是实现抽象主题接口的类。

Proxy:代理角色,内部含有对真实对象RealSubject的引用,从而可以操作真实对象。代理对象提供与真实对象相同的接口,以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

实现动态代理的关键技术是反射。

静态代理

代理模式有几种,虚拟代理,计数代理,远程代理,动态代理。主要分为两类,静态代理和动态代理。静态代理比较简单,是由程序员编写的代理类,并在程序运行前就编译好的,而不是由程序动态产生代理类,这就是所谓的静态。

考虑这样的场景,管理员在网站上执行操作,在生成操作结果的同时需要记录操作日志,这是很常见的。此时就可以使用代理模式,代理模式可以通过聚合和继承两种方式实现:

[java]  view plain   copy
  print ?
  1. /**方式一:聚合式静态代理 
  2.  * @author Goser    (mailto:goskalrie@163.com) 
  3.  * @Since 2016年9月7日 
  4.  */  
  5. //1.抽象主题接口  
  6. public interface Manager {  
  7.     void doSomething();  
  8. }  
  9. //2.真实主题类  
  10. public class Admin implements Manager {  
  11.     public void doSomething() {  
  12.         System.out.println("Admin do something.");  
  13.     }  
  14. }  
  15. //3.以聚合方式实现的代理主题  
  16. public class AdminPoly implements Manager{  
  17.     private Admin admin;  
  18.      
  19.     public AdminPoly(Admin admin) {  
  20.         super();  
  21.         this.admin = admin;  
  22.     }  
  23.    
  24.     public void doSomething() {  
  25.         System.out.println("Log:admin操作开始");  
  26.         admin.doSomething();  
  27.         System.out.println("Log:admin操作结束");  
  28.     }  
  29. }  
  30. //4.测试代码  
  31.         Admin admin = new Admin();  
  32.         Manager m = new AdminPoly(admin);  
  33.         m.doSomething();  
  34. //方式二:继承式静态代理  
  35. //与上面的方式仅代理类和测试代码不同  
  36. //1.代理类  
  37. public class AdminProxy extends Admin {  
  38.     @Override  
  39.     public void doSomething() {  
  40.         System.out.println("Log:admin操作开始");  
  41.         super.doSomething();  
  42.         System.out.println("Log:admin操作开始");  
  43.     }  
  44. }  
  45. //2.测试代码  
  46.         AdminProxy proxy = new AdminProxy();  
  47.         proxy.doSomething();  
聚合实现方式中代理类聚合了被代理类,且代理类及被代理类都实现了同一个接口,可实现灵活多变。继承式的实现方式则不够灵活。

比如,在管理员操作的同时需要进行权限的处理,操作内容的日志记录,操作后数据的变化三个功能。三个功能的排列组合有6种,也就是说使用继承要编写6个继承了Admin的代理类,而使用聚合,仅需要针对权限的处理、日志记录和数据变化三个功能编写代理类,在业务逻辑中根据具体需求改变代码顺序即可。

动态代理

一般来说,对代理模式而言,一个主题类与一个代理类一一对应,这也是静态代理模式的特点。

但是,也存在这样的情况,有n各主题类,但是代理类中的“前处理、后处理”都是一样的,仅调用主题不同。也就是说,多个主题类对应一个代理类,共享“前处理,后处理”功能,动态调用所需主题,大大减小了程序规模,这就是动态代理模式的特点。

JDK动态代理

实现

[java]  view plain   copy
  print ?
  1. //1. 抽象主题  
  2. public interface Moveable {  
  3.     void move()  throws Exception;  
  4. }  
  5. //2. 真实主题  
  6. public class Car implements Moveable {  
  7.     public void move() throws Exception {  
  8.         Thread.sleep(new Random().nextInt(1000));  
  9.         System.out.println("汽车行驶中…");  
  10.     }  
  11. }  
  12. //3.事务处理器  
  13. public class TimeHandler implements InvocationHandler {  
  14.     private Object target;  
  15.      
  16.     public TimeHandler(Object target) {  
  17.         super();  
  18.         this.target = target;  
  19.     }  
  20.    
  21.     /** 
  22.      * 参数: 
  23.      *proxy 被代理的对象 
  24.      *method 被代理对象的方法 
  25.      *args 方法的参数 
  26.      * 返回: 
  27.      *Object 方法返回值 
  28.      */  
  29.     public Object invoke(Object proxy, Method method, Object[] args)  
  30.             throws Throwable {  
  31.         long startTime = System.currentTimeMillis();  
  32.         System.out.println("汽车开始行驶…");  
  33.         method.invoke(target, args);  
  34.         long stopTime = System.currentTimeMillis();  
  35.         System.out.println("汽车结束行驶…汽车行驶时间:" + (stopTime - startTime) + "毫秒!");  
  36.         return null;  
  37.     }  
  38.    
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值