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

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静态代理与动态代理demo

    Java提供了两种实现代理模式的方式:静态代理和动态代理。 **静态代理** 静态代理是在编译时就已经确定了代理类,通过继承或实现目标接口来创建代理类。以下是一个简单的静态代理实现示例: ```java // 目标接口 ...

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

    代理模式通常分为静态代理和动态代理两种类型,这两种代理方式各有特点,适用于不同的场景。 **静态代理** 静态代理是通过程序员手动创建一个代理类来实现的。代理类和真实目标类需要实现相同的接口,以便代理类...

    java静态代理、动态代理、装饰设计模式

    Java提供了两种实现代理的主要方式:静态代理和动态代理。 **静态代理** 静态代理是最基础的形式,它需要程序员手动创建一个代理类,该类实现了与目标类相同的接口。代理类持有目标类的引用,并在调用目标类方法...

    Java 静态代理模式

    Java静态代理模式是一种设计模式,它允许我们为一个对象提供一个代理,以便增强或扩展其功能,同时不改变原有对象的代码。在Java中,静态代理是通过在代理类中显式实现目标接口来实现的。下面将详细介绍静态代理模式...

    Java静态代理和动态代理

    代理模式分为两种主要类型:静态代理和动态代理。 **静态代理** 静态代理是通过程序员手动创建一个代理类来实现的。这个代理类实现了与目标类相同的接口,并且在调用目标方法时添加额外的逻辑。以下是一个简单的...

    Java设计模式——代理设计模式(静态代理和动态代理)

    代理设计模式分为静态代理和动态代理两种类型。 ### 静态代理 静态代理是在编译时就已经确定了代理关系,代理类和真实类的关系是硬编码在代理类中的。下面我们将详细介绍静态代理的实现方式: 1. **定义接口**:...

    java静态代理与动态代理

    ### Java静态代理与动态代理详解 #### 一、代理模式概述 代理模式是软件工程领域中常用的一种设计模式,尤其在Java开发中极为常见。它主要用于控制对某个对象的访问,或者提供额外的功能如日志记录、性能追踪、...

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

    Java提供了两种类型的代理:静态代理和动态代理。 **静态代理** 静态代理是在编译时就已经确定了代理关系。代理类和目标类在代码中是显式定义的,它们通常有相同的接口或基类。以下是一个简单的静态代理实例: ```...

    Java中动态代理的介绍及实例

    动态代理分为静态代理和动态代理两种类型,其中静态代理在源代码级别实现,而动态代理则在运行时动态生成代理类。 #### 二、动态代理的关键概念 - **抽象角色**:通常指接口或抽象类,定义了真实对象和代理对象...

    包含静态代理和动态代理demo代码

    在这个“包含静态代理和动态代理demo代码”的压缩包中,我们可能会看到两种常见的Java代理实现方式的示例:静态代理和动态代理。 首先,我们来详细讲解静态代理。在静态代理中,代理类和真实类(目标类)都是在编译...

    静态代理和动态代理Demo

    静态代理和动态代理是两种常见的代理模式,它们在Java中有着广泛的应用,特别是在SpringBoot等框架中。本资源提供了一个简单的Java实现,适用于JDK1.8版本,并经过了验证,对初学者理解设计模式具有指导意义。 静态...

    静态代理和动态代理

    根据实现方式的不同,代理模式可以分为静态代理和动态代理两种。 ### 静态代理 静态代理是在编译时就已经确定了代理关系。我们需要创建一个代理类,该类实现与目标对象相同的接口,并在代理类的方法中调用目标对象...

    java动态代理类的实例

    在Java中,静态代理是通过定义一个与被代理类实现相同接口的新类来实现的,而动态代理则在运行时动态生成此类,无需预先编写代理类的代码。 `java.lang.reflect.Proxy`类是Java动态代理的核心,它提供了创建代理...

    java动态代理demo

    与静态代理(即手动编写代理类)相比,动态代理无需预先为每个接口编写单独的代理类,使得代码更加灵活且易于维护。 2. **代理接口** 在Java动态代理中,我们首先需要定义一个或多个接口。这些接口定义了原始对象...

    JAVA设计模式之代理模式实例

    代理模式主要分为静态代理和动态代理两种类型。 1. 静态代理 在静态代理中,代理类和目标类是在编译时就已经确定的,它们通常具有相同的接口。客户端通过代理类调用方法,代理类再转发到目标类。以下是一个简单的...

    静态代理和动态代理的讲解和案例,有详细的注释

    本教程将深入探讨静态代理和JDK动态代理的概念、工作原理以及如何实现。 ### 静态代理 静态代理是在编译时就确定了代理类和目标类的关系。代理类和目标类通常都需要实现相同的接口,以便于在代理类中调用目标类的...

    静态代理和动态代理的例子

    代理模式可以分为两种主要类型:静态代理和动态代理。这两种代理方式各有特点,广泛应用于软件系统中,如权限控制、缓存、事务管理等场景。 **静态代理** 静态代理是最基础的代理形式,代理类和被代理类在编译时就...

    Java代理模式Java动态代理

    - **静态方法:** `newProxyInstance`方法用于创建代理类实例,该方法接收三个参数: - `ClassLoader loader`: 定义代理类的类加载器。 - `Class[] interfaces`: 代理类要实现的接口列表。 - `InvocationHandler h`...

    Java 动态代理详解(学习资料)

    在运行时,我们可以动态创建一个实现了特定接口的代理类,从而避免了静态代理的缺点。下面来看看如何使用 JDK 动态代理。首先,我们需要实现 InvocationHandler 接口,这里定义一个 LogInvocationHandler 类public ...

Global site tag (gtag.js) - Google Analytics