`
H_eaven
  • 浏览: 32220 次
  • 性别: Icon_minigender_1
  • 来自: 鲨堡
文章分类
社区版块
存档分类
最新评论

代理与动态代理

阅读更多
代理模式:
 
   public interface Interface {
      void doSomething();
      void somethingElse(String arg);
  }
  public class RealSubject implements Interface {
     public void doSomething() {
          System.out.println("realSubject.doSomething()...");
      }
    public void somethingElse(String arg) {
         System.out.println("realSubject.somethingElse(" + arg + " )...");

    }
}
public class SimpleProxy implements Interface {
   private Interface real;
   public SimpleProxy(Interface obj) {
      this.real = obj;
  }
   public void doSomething() {
      System.out.println("simpleProxy--before");
      real.doSomething();
}
   public void somethingElse(String arg) {
     System.out.println("simpleProxy--before");
     real.somethingElse(arg);
} 
}
public class Main {
   public static void main(String[] args) {
       Interface obj = new RealSubject();
       Interface simpleProxy  = new SimpleProxy(obj);
       simpleProxy.doSomething();
       simpleProxy.somethingElse("testString");
   }
}

这个基本上是最简单的代理模式实现了.
对Interface接口方法的调用,都被SimpleProxy截获了.


动态代理:
能够在运行时实现接口但在编译时不用声明其实现接口的特殊类.////
Java的动态代理比代理的思想又向前了一步.因为它可以动态的创建代理并动态地处理对所有代理的方法调用.在动态代理上所做的所有调用都会被重定向到单一的调用处理器上.(Thinking in Java)
SimpleProxy在编译期已经存在,但动态代理可以在运行期生成代理类,及代理实例.

用动态代理改写上面的例子:
    public class InvocationHandlerImpl implements InvocationHandler {
        private Object target;
        public InvocationHandlerImpl(Object obj) {
           this.target = obj;
}
       public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {
           System.out.println("methodName:" + method.getName());
           System.out.println("proxy:" + proxy.getClass().getName());
           if (args != null) {
              for(Object o : args) {
                  System.out.println(o);
              }
          }
          return method.invoke(target,args);  //1:转发请求
}
} 
  public class Main {
      public static void main(String[] args) {
           Interface real = new RealSubject();
           Interface proxy = (Interface)Proxy.newProxyInstance(Interface.class.getClassLoader(),new Class[]{Interface.class},new InvocationHandlerImpl(real));
          proxy.doSomething();
          proxy.somethingElse("proxyString");
      }
 }


此时可以对多个接口进行方法调用的拦截,AOP的实现.
普通代理模式可能要针对一个接口实现一个代理.
动态代理则只需要编写一个调用处理器的实现类,根据传入的代理接口列表动态生成代理类和代理实例.


   public interface OtherInterface {
      public void play();
   } 

在这里再给出一个接口,但是对这个接口没有默认实现类.
改写上面的调用处理器实现类:

     public class InvocationHandlerImpl2 implements InvocationHandler {
        private Object target;
        public InvocationHandlerImpl2(Object obj) {
           this.target = obj;
}
       public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {
           System.out.println("methodName:" + method.getName());
           System.out.println("proxy:" + proxy.getClass().getName());
           if ("play".equals(method.getName())) {
              System.out.println("invoke OtherInterface.play method!");
         return null;
          }
           if (args != null) {
              for(Object o : args) {
                  System.out.println(o);
              }
          }
          return method.invoke(target,args);
}
} 
public class Main {
      public static void main(String[] args) {
           Interface real = new RealSubject();
           Object proxyObject = Proxy.newProxyInstance(Interface.class.getClassLoader(),new Class[]{Interface.class,OtherInterface.class},new InvocationHandlerImpl2(real));
          Interface proxy = (Interface)proxyObject;
          proxy.doSomething();
          proxy.somethingElse("proxyString");
          OtherInterface otherProxy = (OtherInterface)proxyObject;
          otherProxy.play();
      }
 }


可能的结果:
  methodName:doSomething
proxy:$Proxy0
realSubject.doSomething()...
methodName:somethingElse
proxy:$Proxy0
proxyString
realSubject.somethingElse(proxyString )...
methodName:play
proxy:$Proxy0
invoke OtherInterface.play method!



调用处理器截获对OtherInterface.play()方法的调用.作出处理后并返回,因为没有RealSubject,因些也无法向真实对象进行请求转发.
从外部看:好像Interface的实例经过调用处理器的处理,他又实现了另外一个接口.

现再调用处理器的作用不再只是进行对方法截获进行处理,请求转发;
它实际在做一种实现工作,
(只是进行对方法截获进行处理,而没有进行请求转发就可以看成一种重写了)

再从另个一个角度看,此时的调用处理器不只是进行代理,而还有适配器的形,但可能完全没有适配器的目的,因为Interface和OtherInterface完全没有关系.但可以从一个Interface的实例转型为一个OtherInterface.

甚至在调用Proxy.newProxyInstance()方法生成代理实例的时候,不传入RealSubject对象,那么调用处理器完全冲当代理接口的实现类,而没有了请求转发这一步骤.
不过这完全不是代理的初衷了!
注:1处的转发调用是当有传入RealSubject对象时才可以调用,如果传入null,则要进行单独处理.

动态的意思:1.可以横行为一组接口实现横切逻辑.
          2.可以在运行时动态实现一个接口实例,Proxy$X为接口的实现类.






分享到:
评论

相关推荐

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

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

    java静态代理与动态代理

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

    Java静态代理与动态代理demo

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

    静态代理与动态代理Demo

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

    Java静态代理和动态代理

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

    静态代理和动态代理Demo

    总结来说,这个资源提供了一个理解和实践静态代理与动态代理的好例子。通过学习和运行这些代码,你可以深入理解这两种代理模式的工作原理,以及如何在实际项目中应用它们。同时,这也有助于提升你对Java反射机制的...

    静态代理与动态代理小Demo

    一个静态代理和动态代理的小例子,开发时使用的工具是myeclipse,直接使用myeclipse工具导入即可,希望能 给大家理解这方面的入门知识带来些作用,同时也希望大家指出不足,我可以更加进行改进

    java的动态代理

    #### 五、静态代理与动态代理对比 - **静态代理**:如案例中的`People1TimeProxy`类,它显式地实现了`Speak`接口,并在内部持有`People`对象的引用。这种方式较为僵化,每增加一个接口就需要新增一个代理类。 - **...

    静态代理和动态代理

    代理模式分为两种主要类型:静态代理和动态代理。这两种代理方式在Java中都有广泛的应用,特别是在处理远程调用、事务管理、权限控制等方面。 **静态代理** 静态代理是最基础的代理实现方式,它需要程序员手动创建...

    浅谈JDK动态代理与CGLIB代理去区别

    在Java开发中,动态代理和CGLIB代理是两种常见的面向切面编程(AOP)实现方式,它们都用于在不修改原有代码的情况下,增强或扩展对象的功能。本篇文章将深入探讨JDK动态代理和CGLIB代理的区别,以及它们在实际应用中...

    JDK动态代理_JDK动态代理

    本文将详细介绍JDK动态代理的原理与应用,帮助读者深入理解其工作方式以及如何在实际项目中运用。 #### 二、JDK动态代理简介 JDK动态代理是Java平台提供的一个工具包,用于在运行时创建代理对象。它主要适用于实现...

    JAVA静态代理和动态代理

    Java提供了两种主要的代理实现方式:静态代理和动态代理。 **静态代理** 静态代理是程序员手动创建代理类并实现与目标对象相同的接口。代理类和目标类都必须实现相同的接口,这样代理类就可以在调用目标对象方法的...

    java + 动态代理 + 动态代理实际应用场景

    2: 动态代理demo 举例实际应用场景(载入数据库驱动的时候,使用AIDL与系统Servic进行通信) 3: 动态代理使用到基础理论:ClassLoader 加载.class字节码文件得到 , Class对象, Class对象通过 newProxyInstance ...

    spring+动态代理

    在Spring中,动态代理通常与AOP(面向切面编程)结合使用。AOP允许我们在程序执行过程中,在特定的“切点”插入自定义的行为,如日志、事务管理、权限控制等。Spring AOP通过动态代理机制来实现这些功能,使我们的...

    Java 动态代理.md

    #### 静态代理与动态代理 静态代理是指在编译期就能确定代理对象和目标对象之间的关系。例如,在上面的例子中,程序员通过创建 `UserProxy` 类来代理 `UserDao` 接口的行为。这种方式的优点在于编译期就能确定代理...

    java 动态代理实例(JDK代理与CGLIB代理)

    Java动态代理是Java编程中一个重要的特性,它允许我们在运行时创建对象的代理,从而可以在不修改原有代码的情况下,对原有对象的行为进行扩展或增强。动态代理主要分为两种:JDK代理和CGLIB代理。 **JDK代理**是...

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

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

Global site tag (gtag.js) - Google Analytics