`

[转]代理模式 - 静态代理与动态代理

阅读更多

1. 代理模式主要有两种:静态代理和动态代理 

2. 静态代理: 

比如要在输出“HelloWorld”前打印一个字符串“Welcome” 

A:先定义一个接口类 
Java代码
  1. package ttitfly.proxy;      
  2.      
  3. public interface HelloWorld {      
  4.     public void print();      
  5. //  public void say();      
  6. }   
  7.      
 


B: 定义一个该接口的实现类 

Java代码
  1. package ttitfly.proxy;      
  2.      
  3. public class HelloWorldImpl implements HelloWorld{      
  4.      
  5.     public void print(){      
  6.         System.out.println("HelloWorld");      
  7.     }      
  8. //  public void say(){      
  9. //      System.out.println("Say Hello!");      
  10. //  }      
  11. }     
 


C:定义一个静态代理类 
Java代码
  1. package ttitfly.proxy;      
  2.      
  3. public class StaticProxy implements HelloWorld{      
  4.      
  5.     public HelloWorld helloWorld ;      
  6.     public StaticProxy(HelloWorld helloWorld){      
  7.         this.helloWorld = helloWorld;      
  8.     }      
  9.           
  10.     public void print(){      
  11.         System.out.println("Welcome");      
  12.         //相当于回调      
  13.         helloWorld.print();      
  14.     }      
  15.           
  16. //  public void say(){      
  17. //      //相当于回调      
  18. //      helloWorld.say();      
  19. //  }      
  20. }      
 


D: 一个测试类: 
   
Java代码
  1. package ttitfly.proxy;      
  2.      
  3. public class TestStaticProxy {      
  4.      
  5.     public static void main(String[] args){      
  6.         HelloWorld helloWorld = new HelloWorldImpl();      
  7.         StaticProxy staticProxy = new StaticProxy(helloWorld);      
  8.         staticProxy.print();      
  9.               
  10. //      staticProxy.say();      
  11.     }      
  12. }      


可以看出静态代理类有一个很不爽的缺点:当如果接口加一个方法(把上面所有的代码的注释给去掉),所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。动态代理就可以避免这个缺点。
静态代理的问题:

     1. 一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;

     2. 当如果接口加一个方法(比如上面的say),所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度;

     3.如果事先并不知道真实角色,该如何使用代理呢?

 

采用动态解决以上问题。



3 。动态代理 

动态代理与普通的代理相比较,最大的好处是接口中声明的所有方法都被转移到一个集中的方法中处理(invoke),这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。 

动态代理类只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类 

代理类: 
      
Java代码
  1. package ttitfly.proxy;          
  2.          
  3. import java.lang.reflect.InvocationHandler;          
  4. import java.lang.reflect.Method;          
  5. import java.lang.reflect.Proxy;          
  6. //动态代理类只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类          
  7. public class DynamicProxy implements InvocationHandler{          
  8.               
  9.     private Object object;           
  10.     //绑定关系,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法将被调用时,执行invoke方法。      
  11.     //Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时需要执行哪个InvocationHandler的invoke方法      
  12.     public Object bindRelation(Object object){           
  13.         this.object = object;          
  14.         return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);           
  15.     }           
  16.     //拦截关联的这个实现类的方法被调用时将被执行          
  17.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {           
  18.         System.out.println("Welcome");          
  19.         Object result = method.invoke(object, args);           
  20.         return result;          
  21.     }          
  22.          
  23. }          


测试类: 
     
Java代码
  1. package ttitfly.proxy;          
  2.          
  3. public class TestDynamicProxy {          
  4.     public static void main(String[] args){          
  5.         HelloWorld helloWorld = new HelloWorldImpl();          
  6.         DynamicProxy dp = new DynamicProxy();          
  7.         //在这里绑定的是HelloWorld,也就是HelloWorld是被代理接口。所以绑定关系时,需要传递一个HelloWorld的实现类的实例化对象。          
  8.         HelloWorld helloWorld1 = (HelloWorld)dp.bindRelation(helloWorld);           
  9.         helloWorld1.print();           
  10.         helloWorld1.say();          
  11.               
  12.         //helloWorld2将不被拦截      
  13.         HelloWorld helloWorld2 = new HelloWorldImpl();      
  14.         helloWorld2.print();           
  15.         helloWorld2.say();      
  16.               
  17.     }          
  18. }          

分享到:
评论

相关推荐

    Java中的代理模式--静态代理和动态代理

    Java中的代理模式--静态代理和动态代理 Java中的代理模式--静态代理和动态代理

    代理模式-静态动态代理-jdk动态代理-cglib动态代理

    在Java中,代理模式有多种实现方式,包括静态代理、JDK动态代理和CGLIB动态代理。 **静态代理** 静态代理是最早也是最基础的代理实现方式。在静态代理中,我们需要创建一个代理类,这个代理类与原始类(被代理类)...

    优秀的设计模式示例-静态代理模式

    静态代理模式的核心思想是通过代理类来代理原始对象(也称为真实对象或服务对象),代理类通常与原始对象实现相同的接口,以便在客户端代码中可以透明地调用。代理类可以在调用真实对象的方法前后添加额外的操作,...

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

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

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

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

    Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理)

    Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理) Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解...

    Java 代理 代理模式 静态代理与动态代理 常见的动态代理实现 .md

    静态代理与动态代理的区别 代理模式可以进一步细分为静态代理和动态代理。 - **静态代理**:在程序编译时就已经确定代理类的具体实现方式。这意味着每次需要代理不同的操作时,都需要修改代理类的代码,这违反了...

    Java静态代理和动态代理

    四、静态代理与动态代理的比较 1. **灵活性**:动态代理比静态代理更灵活,因为不需要预先编写代理类的源代码,可以适应接口的变化。 2. **代码量**:静态代理需要为每个委托类编写单独的代理类,如果委托类很多,会...

    代理模式之静态代理---数据库连接池对象实现原理

    在Java中,代理模式主要分为静态代理和动态代理两种。 在本主题“代理模式之静态代理---数据库连接池对象实现原理”中,我们将探讨如何使用静态代理来实现数据库连接池。数据库连接池是现代应用中常用的优化手段,...

    Java 静态代理模式

    静态代理模式是一种结构型设计模式,其核心思想是通过创建一个代理类,这个代理类作为原对象的替代,提供与原对象相同的方法调用,但可以在调用前后添加额外的操作。这种模式在不修改原始对象代码的情况下,可以用于...

    静态代理与动态代理Demo

    代理模式分为静态代理和动态代理两种主要形式,每种都有其特定的应用场景和优势。下面我们将深入探讨这两种代理模式,并通过一个“黄牛买票”的例子来具体说明。 首先,我们来看静态代理。静态代理是程序员在编译时...

    Java设计模式-代理模式例子

    在Java中,代理模式主要有静态代理和动态代理两种实现方式。 1. 静态代理:在编译时就已经确定了代理类与目标类的关系。通常,代理类会实现和目标类相同的接口,以便于在代理类中调用目标类的方法。这种方式的缺点...

    Spring学习笔记(12)----静态代理模式分析演示

    在本篇Spring学习笔记中,我们将探讨静态代理模式在Spring框架中的应用与分析。静态代理是一种常见的设计模式,它在不修改目标类代码的情况下,通过代理类来扩展或增强目标类的功能。在Spring中,静态代理主要应用于...

    JAVA静态代理和动态代理

    静态代理是程序员手动创建代理类并实现与目标对象相同的接口。代理类和目标类都必须实现相同的接口,这样代理类就可以在调用目标对象方法的同时添加额外的功能。以下是一个简单的静态代理模式示例: 1. 定义接口: ...

    代理模式的各种实现 (动态代理、静态代理)

    代理模式在Java中主要有两种实现方式:静态代理和动态代理,其中动态代理又分为JDK动态代理和CGlib代理。 1. 静态代理 静态代理是程序员手动创建代理类并实现与目标类相同接口的方式。在静态代理中,代理类和目标类...

    设计模式-代理模式-java

    在Java中,代理模式可以通过多种方式实现,包括静态代理、动态代理(JDK动态代理和CGLIB动态代理)等。 **静态代理** 静态代理是最基础的代理形式,需要手动创建一个代理类,该类继承或实现与目标类相同的接口,并...

    代理模式_静态代理.zip

    设计模式之代理模式_静态代理的一个java实现的demo。主类在Client中。仅代码实现,可供初学者参考使用

    Java静态代理与动态代理demo

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

    java 设计模式之代理模式(Proxy Pattern)实现代码及设计详解:动态代理模式、静态代理模式

    代理模式分为两种主要类型:静态代理和动态代理。 **静态代理** 在静态代理中,代理类和目标类都是在编译时就已经确定的。我们首先创建一个目标类接口,然后创建一个实现这个接口的代理类,同时代理类还持有目标类...

Global site tag (gtag.js) - Google Analytics