Proxy动态代理机制的Java实现

动态代理Proxy

    代理模式是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个真实对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。

    通过代理层这一中间层,有效的控制对于真实委托类对象的直接访问,同时可以实现自定义的控制策略(Spring的AOP机制),设计上获得更大的灵活性。

下面,举一个简单例子(在小猫吃鱼的基础上添加打印日志的功能),来模拟动态代理机制的原理


动态代理机制的步骤


1、定义被代理对象Cat.java和其实现的接口Animal

Proxy动态代理机制的Java实现

Proxy动态代理机制的Java实现

 2、声明父接口InvocationHandler

 Proxy动态代理机制的Java实现

3、定义“日志打印”的实现类LogHandler

Proxy动态代理机制的Java实现

4、模拟动态代理类Proxy.java,jdk中的Proxy类会利用“反射”机制,动态地帮助我们生成下面地Java代码,并且直接编译成二进制的class文件,装载到类加载器中。

Proxy动态代理机制的Java实现

Proxy动态代理机制的Java实现

      Proxy动态代理机制的Java实现

Proxy动态代理机制的Java实现

5、Test类

Proxy动态代理机制的Java实现

结果:

开始打印

Cat eats fish

结束打印

开始打印

喵喵喵...

结束打印

开始打印

在北京跑了20米

结束打印

在d:/Software/eclipse/com/oracle/dynamicProxy/目录下,生成的$Proxy1.java如下:

package com.oracle.dynamicProxy;
import java.lang.reflect.Method;
public class $Proxy1 implements com.oracle.dynamicProxy.Animal{
    public com.oracle.dynamicProxy.InvocationHandler h;
    private Object[] args=null;
    public $Proxy1(com.oracle.dynamicProxy.InvocationHandler h){
        this.h = h;
    }
@Override
 public void run(int foo,java.lang.String uja){
    try{
      Method md = com.oracle.dynamicProxy.Animal.class.getMethod("run",int.class,String.class);
      args = new Object[]{foo,uja};
      h.invoke(this, md, args);
    }catch(Exception e){
     e.printStackTrace();
    }
  }@Override
 public void eat(java.lang.String ipj){
    try{
      Method md = com.oracle.dynamicProxy.Animal.class.getMethod("eat",String.class);
      args = new Object[]{ipj};
      h.invoke(this, md, args);
    }catch(Exception e){
     e.printStackTrace();
    }
  }@Override
 public void sound(){
    try{
      Method md = com.oracle.dynamicProxy.Animal.class.getMethod("sound");
      args = null;
      h.invoke(this, md, args);
    }catch(Exception e){
     e.printStackTrace();
    }
  }
}