zoukankan      html  css  js  c++  java
  • Java 动态代理 Demo

      相比于静态代理,动态代理避免了开发者编写各个繁锁的静态代理类,只需指定一组接口及目标类对象就能动态地获取代理对象。

      

      使用动态代理的六大步骤:

      1 通过实现InvocationHandler接口来自定义自己的InvocationHandler。

      2 通过Proxy类的getProxyClass方法获取代理类。

      3 通过反射机制获取代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)。

      4 将目标对象作为参数传入,通过构造方法获取自定义的InvocationHandler实例对象。

      5 将自定义的InvocationHandler实例对象作为参数传入,通过构造方法获取代理对象。

      6 代理对象调用目标方法。

      JDK Proxy HelloWorld

    1 package com.yao.proxy;
    2 
    3 public interface Helloworld {
    4     void sayHello();
    5 }
    1 package com.yao.proxy;
    2 
    3 import com.yao.HelloWorld;
    4 
    5 public class HelloworldImpl implements HelloWorld {
    6     public void sayHello() {
    7         System.out.print("hello world");
    8     }
    9 }
     1 package com.yao.proxy;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 
     6 public class MyInvocationHandler implements InvocationHandler{
     7     private Object target;
     8     public MyInvocationHandler(Object target) {
     9         this.target=target;
    10     }
    11     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    12         System.out.println("method :"+ method.getName()+" is invoked!");
    13         return method.invoke(target,args); // 执行相应的目标方法 
    14     }
    15 }

       target属性表示代理的目标对象。InvocationHandler是连接代理对象与目标对象的自定义中间类MyInvocationHandler必须实现的接口,只有一个方法public Object invoke(Object proxy, Method method, Object[] args)。在这个方法中,Proxy通过newProxyInstance方法创建代理对象,method表示目标对象被调用的方法,args表示目标对象被调用方法的形参列表。

     1 package com.yao.proxy;
     2 
     3 import com.yao.HelloWorld;
     4 import java.lang.reflect.Constructor;
     5 import java.lang.reflect.InvocationHandler;
     6 import java.lang.reflect.InvocationTargetException;
     7 import java.lang.reflect.Proxy;
     8  
     9 public class JDKProxyTest {
    10     public static void main(String[]args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
    11         // 这里有两种写法,采用复杂的一种写法,有助于理解。
    12         Class<?> proxyClass= Proxy.getProxyClass(JDKProxyTest.class.getClassLoader(),HelloWorld.class);
    13         final Constructor<?> cons = proxyClass.getConstructor(InvocationHandler.class);
    14         final InvocationHandler ih = new MyInvocationHandler(new HelloworldImpl());
    15         HelloWorld helloWorld = (HelloWorld)cons.newInstance(ih);
    16         helloWorld.sayHello();
    17  
    18         // 下面是简单的一种写法,本质上和上面是一样的
    19         /* 
    20         HelloWorld helloWorld=(HelloWorld)Proxy.
    21                  newProxyInstance(JDKProxyTest.class.getClassLoader(),
    22                         new Class<?>[]{HelloWorld.class},
    23                         new MyInvocationHandler(new HelloworldImpl()));
    24         helloWorld.sayHello();
    25         */
    26     }
    27  
    28 }

      

      参考资料

      深度剖析JDK动态代理机制

      JDK动态代理详解

      JDK动态代理源码解析

  • 相关阅读:
    Django安装和启动
    转载:Python 包管理工具解惑
    电子商务的基本理念
    javascript的循环使用
    错误码
    weex初始
    Flex 布局
    css样式重置表
    手机端页面自适应解决方案—rem布局
    实用的60个CSS代码片段[下]
  • 原文地址:https://www.cnblogs.com/WJQ2017/p/7688317.html
Copyright © 2011-2022 走看看