`
aijuans
  • 浏览: 1548386 次
社区版块
存档分类
最新评论

Java静态代理、动态代理实例

阅读更多

采用Java代理模式,代理类通过调用委托类对象的方法,来提供特定的服务。委托类需要实现一个业务接口,代理类返回委托类的实例接口对象。

按照代理类的创建时期,可以分为:静态代理和动态代理。

所谓静态代理: 指程序员创建好代理类,编译时直接生成代理类的字节码文件。

所谓动态代理: 在程序运行时,通过反射机制动态生成代理类。

 

一、静态代理类实例:

1、Serivce.java

 

Java代码 
  1. package com.ibm.delegate;  
  2.   
  3. /** 
  4.  * 定义一个服务接口 
  5.  * @author IBM 
  6.  */  
  7. public interface Service {  
  8.       
  9.     /** 
  10.      * 查询日期 
  11.      */  
  12.     public String queryDate();  
  13.     /** 
  14.      * 计算两个整数之差 
  15.      */  
  16.     public int sub(int a, int b);  
  17. }  

 

2、ServiceImpl.java

 

Java代码 
  1. package com.ibm.delegate;  
  2.   
  3. import java.util.Date;  
  4.   
  5. /** 
  6.  * 委托类需要实现服务接口(必须) 
  7.  * @author IBM 
  8.  */  
  9. public class CountImpl implements Service {  
  10.   
  11.     @Override  
  12.     public String queryDate() {  
  13.         return new Date().toString();  
  14.     }  
  15.   
  16.     @Override  
  17.     public int sub(int a, int b) {  
  18.         return a-b;  
  19.     }  
  20.       
  21.     public void ownMethod(){  
  22.         System.out.println("It's my own method");  
  23.     }  
  24. }  
3、ServiceProxy.java

 

 

Java代码 
  1. package com.ibm.staticproxy;  
  2.   
  3. import com.ibm.delegate.Serivce;  
  4. import com.ibm.delegate.CountImpl;  
  5.   
  6. /** 
  7.  * @author IBM 
  8.  * 静态代理类 
  9.  */  
  10. public class SerivceProxy implements Service {  
  11.     private CountImpl countImpl;  
  12.       
  13.     public SerivceProxy(CountImpl countImpl){  
  14.         this.countImpl = countImpl;  
  15.     }  
  16.       
  17.     @Override  
  18.     public String queryDate() {  
  19.         return countImpl.queryDate();  
  20.     }  
  21.   
  22.     @Override  
  23.     public int sub(int a, int b) {  
  24.         return countImpl.sub(a, b);  
  25.     }  
  26.       
  27.     public void ownMethod(){  
  28.         System.out.println("It's my own method");  
  29.     }  
  30. }  
4、ServiceTest.java(测试类)

 

 

Java代码 
  1. package com.ibm;  
  2.   
  3. import com.ibm.delegate.ServiceImpl;  
  4. import com.ibm.staticproxy.ServiceProxy;  
  5.   
  6. public class ServiceTest {  
  7.   
  8.     /** 
  9.      * @param args 
  10.      */  
  11.     public static void main(String[] args) {  
  12.         //创建委托类实例,即被代理的类对象  
  13.         ServiceImpl target = new ServiceImpl();  
  14.         //创建静态代理类  
  15.         ServiceProxy proxy = new ServiceProxy(target);  
  16.         String date = proxy.queryDate();  
  17.         System.out.println(date);  
  18.         int result = proxy.sub(1020);  
  19.         System.out.println("10-20 = "+result);  
  20.         proxy.ownMethod();  
  21.     }  
  22. }  

静态代理类的特点: 代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。而且代理类只能为特定的接口(Service)服务。

 


动态代理实例:

3、ServiceProxy.java

 

Java代码 
  1. package com.ibm.dynamicproxy;  
  2.   
  3. import java.lang.reflect.InvocationHandler;  
  4. import java.lang.reflect.Method;  
  5. import java.lang.reflect.Proxy;  
  6.   
  7. public class ServiceProxy implements InvocationHandler {  
  8.   
  9.     private Object target;  
  10.       
  11.     public ServiceProxy(Object target){  
  12.         this.target = target;  
  13.     }  
  14.       
  15.     @Override  
  16.     public Object invoke(Object proxy, Method method, Object[] args)  
  17.             throws Throwable {  
  18.         Object result = null;  
  19.         result = method.invoke(target, args);  
  20.         return result;  
  21.     }  
  22.       
  23.     /** 
  24.      * @param target 
  25.      * @return 返回委托类接口的实例对象 
  26.      */  
  27.     public Object getProxyInstance(){  
  28.         return Proxy.newProxyInstance(target.getClass().getClassLoader(),   
  29.                 target.getClass().getInterfaces(), this);  
  30.     }  
  31. }  
4、ServiceTest.java(测试类)

 

 

Java代码 
  1. package com.ibm;  
  2.   
  3. import com.ibm.delegate.Service;  
  4. import com.ibm.delegate.ServiceImpl;  
  5. import com.ibm.dynamicproxy.ServiceProxy;  
  6.   
  7. public class ServiceTest {  
  8.   
  9.     /** 
  10.      * @param args 
  11.      */  
  12.     public static void main(String[] args) {  
  13.         //创建委托类实例,即被代理的类对象  
  14.         ServiceImpl target = new ServiceImpl();  
  15.         //创建动态代理类  
  16.         ServiceProxy proxy = new ServiceProxy(target);  
  17.         Service service = (Service) proxy.getProxyInstance();  
  18.         String date = service.queryDate();  
  19.         System.out.println(date);  
  20.         int result = service.sub(1020);  
  21.         System.out.println("10-20 = "+result);  
  22.     }  
  23. }  

 

动态代理: 代理类需要实现InvocationHandler接口。

使用场合举例: 如果需要委托类处理某一业务,那么我们就可以先在代理类中,对客户的权限、各类信息先做判断,如果不满足某一特定条件,则将其拦截下来,不让其代理。

 

修改两个方法,做测试:

ServiceImpl.java

 

Java代码 
  1. public String ownMethod(){  
  2.     System.out.println("It's my own method");  
  3.     return "user";  
  4. }  

 

ServiceProxy.java

 

Java代码 
  1. @Override  
  2. public Object invoke(Object proxy, Method method, Object[] args)  
  3.         throws Throwable {  
  4.     Object result = null;  
  5.     if(!(target instanceof ServiceImpl)){  
  6.         System.out.println("不能代理该对象");  
  7.         return result;  
  8.     }else if(!((ServiceImpl)target).ownMethod().equals("admin")){  
  9.         System.out.println("权限不够");  
  10.         return result;  
  11.     }  
  12.     result = method.invoke(target, args);  
  13.     return result;  
  14. }  


 


16
4
分享到:
评论
10 楼 Link028 2012-07-16  
是我没表达清楚?还是你没看清楚?
答非所问。
9 楼 JamesQian 2012-07-02  
通过dynamic proxy 可以实现对其权限动态的处理,不错
8 楼 暗夜幽魂 2012-06-27  
Link028 写道
探讨下:
动态代理实现
ServiceImpl target = new ServiceImpl(); 
        //创建动态代理类 
        ServiceProxy proxy = new ServiceProxy(target); 
        Service service = (Service) proxy.getProxyInstance();

新建  代理类对象 ServiceProxy proxy 时已经将委托对象传递进来了,
然后 调用   Service service = (Service) proxy.getProxyInstance();得到接口是不是
多此一举了?感觉直接用 target 不就OK了吗?


用动态代理往往是要实现一些诸如:日志,权限等功能的插入。直接调用target就没办法实现这些额外功能。 例如本文中的权限控制。建议可以看一下spring中的AOP原理 就会明白了。
7 楼 w156445045 2012-06-27  
感觉没怎么说清楚,
6 楼 xlaohe1 2012-06-27  
我看见了IBM
5 楼 Link028 2012-06-27  
探讨下:
动态代理实现
ServiceImpl target = new ServiceImpl(); 
        //创建动态代理类 
        ServiceProxy proxy = new ServiceProxy(target); 
        Service service = (Service) proxy.getProxyInstance();

新建  代理类对象 ServiceProxy proxy 时已经将委托对象传递进来了,
然后 调用   Service service = (Service) proxy.getProxyInstance();得到接口是不是
多此一举了?感觉直接用 target 不就OK了吗?
4 楼 elan1986 2012-06-26  
3 楼 cpszy 2012-06-26  
对我有帮助,谢谢博主!
2 楼 xuelianbobo 2012-06-26  
1 楼 xpp02 2012-06-25  
动态代理,真的很好用的说

相关推荐

    java 静态代理和动态代理学习实例源码

    java static proxy dynamic proxy

    java 代理(动态、静态)实例

    java 代理(动态、静态)实例:该资源包括java的动态代理和静态代理实例,代理里并有详细的注释。

    Java动态代理静态代理实例分析

    主要介绍了Java动态代理静态代理实例分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    JAVA 范例大全 光盘 资源

    实例201 Servlet生成的动态图片 658 实例202 简单的JSP上传文件 661 实例203 用Servlet获取Web服务器信息 666 实例204 可选择的图形验证码 670 实例205 简单的页面注册 675 实例206 用Servlet实现分页查看...

    java范例开发大全

    第1篇 Java编程基础 第1章 Java开发环境的搭建(教学视频:9分钟) 2 1.1 理解Java 2 1.2 搭建Java所需环境 3 1.2.1 下载JDK 3 ...实例290 LAN使用代理服务器 562 实例291 BBS论坛服务器端 567 实例292 ...

    Java+单例+多例+工厂+枚举+动态代理===》演示

    单例设计模式案例演示 单例模式,是一种常用的软件设计模式。通过单例模式可以保证系统中,**应用该模式的这个类只有一个实例**。即一个类只有一个对象实例。 #### 单例设计模式实现步骤 ...动态代理案例演示

    java范例开发大全源代码

     实例154 使用静态成员变量计算内存中实例化的对象数目 239  实例155 实现加减乘除的方法 240  8.3 面向对象的设计模式 241  实例156 Singleton单例模式 242  实例157 招聘(简单工厂模式) 243  ...

    Java JDK实例宝典

    全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...

    ProxyDemo:java动态代理的demo

    ###1.2静态代理代理类在程序运行前已经存在的代理方式成为静态代理。通过上面解释可以知道,由开发人员编写或是编译器生成代理类的方式都属于静态代理。源码中实现了一个静态代理的实例:ClassA 是委托类 , ClassB...

    Java范例开发大全(全书源程序)

    实例216 动态的数组链表 382 实例217 你能猜出鱼是谁的宠物吗? 387 实例218 使用Collections类对List的排序操作 393 实例219 LinkedList的添加删除操作 395 实例220 运用Vector 397 实例221 改变Properties...

    Java范例开发大全 (源程序)

     实例216 动态的数组链表 382  实例217 你能猜出鱼是谁的宠物吗? 387  实例218 使用Collections类对List的排序操作 393  实例219 LinkedList的添加删除操作 395  实例220 运用Vector 397  实例221 改变...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例161 反射与动态代理 209 7.3 常见的未检查型异常 210 实例162 算数异常 210 实例163 数组存值异常 211 实例164 数组下标越界异常 212 实例165 空指针异常 213 7.4 常见的已检查型异常 214 实例166 类未发现异常 ...

    java范例开发大全(pdf&源码)

    实例216 动态的数组链表 382 实例217 你能猜出鱼是谁的宠物吗? 387 实例218 使用Collections类对List的排序操作 393 实例219 LinkedList的添加删除操作 395 实例220 运用Vector 397 实例221 改变Properties文件中的...

    Java 基础核心总结 +经典算法大全.rar

    静态代理与动态代理常见的动态代理实现JDK Proxy CGLIB JDK Proxy 和 CGLIB 的对比动态代理的实际应用 Spring AOP 变量 变量汇总实例变量 实例变量的特点全局变量 静态变量 静态变量的特点类变量 局部变量

    Java面向对象系列[v1.0.0][使用反射生成动态代理]

    Proxy提供了用于创建动态代理类和代理对象的静态方法,他也是所有动态代理类的父类,如果在程序中为一个或多个接口动态的生成实现类,就可以使用Proxy来创建动态代理类,如果需要为一个或多个接口动态的创建实例,也...

Global site tag (gtag.js) - Google Analytics