首页 > 代码库 > 动态代理

动态代理

软件151  汪佳宁

 

动态代理
     概念:动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
      2、动态代理实现步骤
           具体步骤是:
           a. 实现InvocationHandler接口创建自己的调用处理器
           b. 给Proxy类提供ClassLoader和代理接口类型数组创建动态代理类
           c. 以调用处理器类型为参数,利用反射机制得到动态代理类的构造函数
           d. 以调用处理器对象为参数,利用动态代理类的构造函数创建动态代理类对象
       

           分步骤实现动态代理
          Java代码 
            // InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
            // 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用
            InvocationHandler handler = new InvocationHandlerImpl(..);
            // 通过 Proxy 为包括 Interface 接口在内的一组接口动态创建代理类的类对象
             Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... });
            // 通过反射从生成的类对象获得构造函数对象
             Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class });
           // 通过构造函数对象创建动态代理类实例
           Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler });
           Proxy类的静态方法newProxyInstance对上面具体步骤的后三步做了封装,简化了动态代理对象的获取过程。

         简化后的动态代理实现
          Java代码 
          // InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
           InvocationHandler handler = new InvocationHandlerImpl(..);

          // 通过 Proxy 直接创建动态代理类实例
           Interface proxy = (Interface)Proxy.newProxyInstance( classLoader,
           new Class[] { Interface.class }, handler );
      3、动态代理实现示例
          创建自己的调用处理器
          Java代码  
               /**
               * 动态代理类对应的调用处理程序类
               */
               public class SubjectInvocationHandler implements InvocationHandler {

              //代理类持有一个委托类的对象引用
                 private Object delegate;
                 public SubjectInvocationHandler(Object delegate) {
                 this.delegate = delegate;
                        }
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 long stime = System.currentTimeMillis();
               //利用反射机制将请求分派给委托类处理。Method的invoke返回Object对象作为方法执行结果。
               //因为示例程序没有返回值,所以这里忽略了返回值处理
                method.invoke(delegate, args);
                long ftime = System.currentTimeMillis();
                System.out.println("执行任务耗时"+(ftime - stime)+"毫秒");

                 return null;
                  }
                  }
   

             生成动态代理对象的工厂,工厂方法列出了如何生成动态代理类对象的步骤。
             Java代码 
              /**
               * 生成动态代理对象的工厂.
              */
                public class DynProxyFactory {
               //客户类调用此工厂方法获得代理对象。
               //对客户类来说,其并不知道返回的是代理类对象还是委托类对象。
                public static Subject getInstance(){
                 Subject delegate = new RealSubject();
                 InvocationHandler handler = new SubjectInvocationHandler(delegate);
                Subject proxy = null;
                proxy = (Subject)Proxy.newProxyInstance(
                delegate.getClass().getClassLoader(),
                delegate.getClass().getInterfaces(),
                 handler);
                 return proxy;
                   }
                    }
           动态代理客户类
                  Java代码 
                  public class Client {
                   public static void main(String[] args) {
                   Subject proxy = DynProxyFactory.getInstance();
                   proxy.dealTask("DBQueryTask");
                        }
                       }

动态代理