Java静动态代理模式示例

开发 后端
静态代理模式中,真实角色必须是事先已经存在的,并将其作为代理对象的内部属性,并且真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀。那么,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决。

设计模式
1.静态代理模式
使用场合:

为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
涉及的角色:
抽象角色:
声明真实对象和代理对象的共同接口;

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

真实角色:
代理角色所代表的真实对象,是我们最终要引用的对象。
***的老师是代码,下面是本人敲的一个静态代理代码示例 

Java代码 收藏代码

  1. package com;    
  2. /**   
  3.  * 车站接口-【抽象角色】   
  4.  *    
  5.  * @author abing   
  6.  *    
  7.  */    
  8. interface Station {    
  9.     void sellTicks();// 卖票    
  10.     void transport();// 运输乘客    
  11. }    
  12. /**   
  13.  * 火车站实现类-【具体角色】   
  14.  *    
  15.  * @author abing   
  16.  *    
  17.  */    
  18. class TrainStationImpl implements Station {    
  19.     @Override    
  20.     public void sellTicks() {    
  21.         System.out.println("TrainStation  sell tickets");    
  22.     }    
  23.     @Override    
  24.     public void transport() {    
  25.         System.out.println("TrainStation  transport passenger");       
  26.     }    
  27. }    
  28. /**   
  29.  * 该类做为火车站的一个代理直接供客户端调用-【代理角色】   
  30.  *    
  31.  * @author abing   
  32.  *    
  33.  */    
  34. class StationProxy implements Station {    
  35.     Station sta = new TrainStationImpl();    
  36.     @Override    
  37.     public void sellTicks() {    
  38.         sta.sellTicks();//代理类中调用真实角色的方法。    
  39.     }    
  40.     public void otherOperate() {    
  41.         System.out.println("do some other things...");    
  42.     }    
  43.     @Override    
  44.     public void transport() {    
  45.         System.out.println("StationProxy can not transport");    
  46.     }    
  47. }    
  48. /**   
  49.  * 客户端测试类   
  50.  *    
  51.  * @author abing   
  52.  *    
  53.  */    
  54. public class StaticProxyDemo {    
  55.     public static void main(String[] args) {    
  56.         Station station = new StationProxy();//客户端直接操作代理类,避免了客户端与真实类的直接交涉    
  57.         station.sellTicks();    
  58.     }    

#p#

2.动态代理模式

静态代理模式中,真实角色必须是事先已经存在的,并将其作为代理对象的内部属性,并且真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀。那么,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决。
动态代理必需用到以下两个类。
(1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。用于完成真实角色中方法的调用。(2).Proxy:该类即为动态代理类,作用类似于静态代理模式的代理类
***的老师是代码,下面是本人敲的一个动态代理代码示例

Java代码 收藏代码

  1. package com.proxy;    
  2. import java.lang.reflect.InvocationHandler;    
  3. import java.lang.reflect.Method;    
  4. import java.lang.reflect.Proxy;    
  5. /**   
  6.  * 车站接口-【抽象角色】   
  7.  * @author abing   
  8.  *   
  9.  */    
  10. interface Station {    
  11.     void sellTicks();// 卖票    
  12. }    
  13. /**   
  14.  * 火车站实现类-【具体角色】   
  15.  * @author abing   
  16.  *   
  17.  */    
  18. class TrainStationImpl implements Station {    
  19.     @Override    
  20.     public void sellTicks() {    
  21.         System.out.println("TrainStation  sell tickets");    
  22.     }    
  23. }    
  24. /**   
  25.  * 使用动态代理模式必须实现InvocationHandler接口,该接口中仅定义了一个方法:   
  26.  * invoke(Object obj,Method method, Object[] args)。   
  27.  * 在实际使用时,***个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组   
  28.  *    
  29.  * @author abing   
  30.  *   
  31.  */    
  32. class InvocationHandlerImpl implements InvocationHandler {    
  33.     Object proxyobj;    
  34.     public InvocationHandlerImpl(Object object) {    
  35.         this.proxyobj = object;    
  36.     }    
  37.     @Override    
  38.     public Object invoke(Object obj, Method method, Object[] args)    
  39.             throws Throwable {    
  40.         System.out.println("start doing  .........");    
  41.         method.invoke(proxyobj, args);//调用被代理对象proxyobj的方法method,传入一个参数组args    
  42.         System.out.println("stop doing  .........");    
  43.         return null;    
  44.     }    
  45. }    
  46. /**   
  47.  * 客户端测试类   
  48.  * @author abing   
  49.  *   
  50.  */    
  51. public class DynamicProxyDemo {    
  52.     public static void main(String[] args) {    
  53.         Station stationImpl = new TrainStationImpl();//将要被代理的真实对象    
  54.         /**   
  55.          * 动态代理就好处在这里,不管这里是要代理什么对象,I   
  56.          * nvocationHandlerImpl与Proxy中代码都不必改变,   
  57.          * 都是用下面同样的方式去产生代理对象   
  58.          */    
  59.         InvocationHandler handler = new InvocationHandlerImpl(stationImpl);//用InvocationHandler的实现类包装真实的被代理角色    
  60.         ClassLoader loader = handler.getClass().getClassLoader();//获取当期那java程序的类装在器Classloadler    
  61.         Class<?>[] interfaces = stationImpl.getClass().getInterfaces();//获取被代理角色实现的所有接口    
  62.         /**   
  63.          * Proxy类是动态代理模式涉及到的另一个重要的类,该类即为动态代理类,作用类似于静态代理模式中的代理类StationProxy,   
  64.          * 它有一个重要方法tatic Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例。   
  65.          * 其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组,传递此参数以使产生的代理对象可以当做真实类任意实现接口的子类来用,   
  66.          * h是调用处理器InvocationHandler。    
  67.          */    
  68.         Station station = (Station) Proxy.newProxyInstance(loader, interfaces,handler);    
  69.         station.sellTicks();//将会去执行DynamicProxy的invoke方法,完成对目标对象方法的调用    
  70.     }    

原文链接:http://kuru.iteye.com/blog/1261562

编辑推荐:

  1. 红帽云中Java提供综合生命周期支持
  2. 纯Java进程内缓存框架Ehcache 2.5正式发布
  3. 深入浅出Rhino:Java与JS互操作
  4. JavaScript异步编程之Jscex无创痕切入jQueryUI
  5. Java开发框架Play框架快速入门
责任编辑:林师授 来源: kuru的博客
相关推荐

2011-04-06 11:41:25

Java动态代理

2023-02-24 07:42:30

Java动态代理

2011-03-23 10:40:51

java代理模式

2012-08-28 10:59:26

JavaJava动态代理Proxy

2017-10-12 14:56:11

2015-09-22 11:09:47

Java 8动态代理

2023-12-06 08:23:44

代理模式设计模式

2015-09-28 15:59:00

Java动态代理机制

2021-07-06 06:39:22

Java静态代理动态代理

2017-05-11 21:30:01

Android动态代理ServiceHook

2015-09-24 08:54:36

java动态代理

2015-09-24 08:55:14

Java动态代理扩展

2021-09-08 07:18:30

代理模式对象

2010-04-21 09:26:54

Java动态代理

2012-02-08 10:12:19

Java反射

2020-04-27 07:28:00

Java反射动态代理

2012-02-29 09:41:14

JavaScript

2012-01-13 15:59:07

2021-06-29 08:54:23

设计模式代理模式远程代理

2011-11-21 12:56:10

Java代理模式设计模式
点赞
收藏

51CTO技术栈公众号