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

    本文主要讲解的是JDK动态代理的使用方法

    JDK动态代理只能代理接口。

    java.lang.reflect.Proxy为JDK的代理类,它为创建动态代理类和实例提供了一些静态方法,

    并且它是所有用这些方法创建出来的动态代理类的父类。

    以下是Proxy类源码注释中提供的创建动态代理类的两种方法:

    <p>To create a proxy for some interface {@code Foo}:
    * <pre>

    第一种方法:
    * InvocationHandler handler = new MyInvocationHandler(...);
    * Class proxyClass = Proxy.getProxyClass(
    * Foo.class.getClassLoader(), new Class[] { Foo.class });
    * Foo f = (Foo) proxyClass.
    * getConstructor(new Class[] { InvocationHandler.class }).
    * newInstance(new Object[] { handler });
    * </pre>
    * or more simply:

    第二种更简洁的方法:
    * <pre>
    * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
    * new Class[] { Foo.class },
    * handler);
    * </pre>

    下面再介绍一下java.lang.reflect.InvocationHandler接口:

    它是一个代理实例的调用处理器,每一个代理实例都有一个相关的调用处理器,

    当一个方法在代理实例上被调用时,方法调用将会被编码并且转发到它的调用处理器的invoke方法上。

    我们自己编写的调用处理器必须实现此接口,并且重写其中的invoke方法。

    接下来我们来写一些代码来尝试一下JDK动态代理的流程:

    第一步:

    需要注意的是JDK动态代理的对象必须是interface类型的即接口。

    所以我们先创建一个简单的接口:

    public interface Fruit {
        void say();
    
    }

    再编写一个它的实现类:

    public class Apple implements Fruit {
    
        @Override
        public void say() {
            // TODO Auto-generated method stub
            System.out.println("I am apple");
        }
    
    }

    接下来编写一个调用处理器:

    
    

    public class CustomInvocationHandler implements InvocationHandler {

    
    

    private Object object;
    public CustomInvocationHandler(Object obj){
    this.object = obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    System.out.println("方法调用前");
    Object result = method.invoke(object, args);
    System.out.println("方法调用后");
    return result;
    }

    
    

    }

     

    最后编写一个main方法来测试:

    
    

    public class JDKproxy {

    
    

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {

    InvocationHandler handler = new CustomInvocationHandler(new Apple());
    // 第一种方法:
    // Class<?> proxyClass = Proxy.getProxyClass(
    // Fruit.class.getClassLoader(), new Class[] { Fruit.class });
    // Fruit f = (Fruit) proxyClass.
    // getConstructor(new Class[] { InvocationHandler.class }).
    // newInstance(new Object[] { handler });
    // f.say();
    // 第二种方法:
    Fruit f = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(),new Class[] { Fruit.class },handler);
    f.say();
    }

    
    

    }

     

    运行一下,看一下测试结果是:

    方法调用前
    I am apple
    方法调用后

    以上就是JDK动态代理的使用方法。

  • 相关阅读:
    VSCode拓展插件推荐(HTML、Node、Vue、React开发均适用)
    算法_栈的Java的通用数组实现
    算法_计算输入的算术表达式的值.
    设计模式整理_组合模式
    JavaSE复习_9 集合框架复习
    一个小题目的三种不同的解法
    设计模式整理_状态模式
    设计模式整理_迭代器模式
    设计模式整理_模板模式
    JavaSE复习_8 泛型程序设计
  • 原文地址:https://www.cnblogs.com/CLAYJJ/p/5978593.html
Copyright © 2011-2022 走看看