代理模式之JDK动态代理

Posted gaopengpy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代理模式之JDK动态代理相关的知识,希望对你有一定的参考价值。

代理类在程序运行时创建的代理方式被称为动态代理。

JDK动态代理实现原理

动态代理机制

1、通过实现 InvocationHandler 接口创建自己的调用处理器

2、通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类

3、通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型

4、通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入

实现代码如下:

接口:

public interface Person {
    // 上交班费
    void giveMoney();
}

 

接口实现类:

public class Student implements Person {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    public void giveMoney() {
        System.out.println(name + "上交班费50元");
    }
}

 

代理类:

package com.gaopeng.springboot.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class StuInvocationHandler implements InvocationHandler {
    //invocationHandler持有的被代理对象
    // 如果知道,被代理类的类型,可以在这里直接设定特定类型,需要注意的是
    // 在invoke()方法中也需要转为相应类型,而不能使用O
    Object target;

    public StuInvocationHandler(Object target) {
        this.target = target;
    }
    /**
     * proxy:代表动态代理对象
     * method:代表正在执行的方法
     * args:代表调用目标方法时传入的实参
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理执行" +method.getName() + "方法");
        // 在方法调用之前进行系列操作,这里可以是方法
        System.out.println("Before the function");
        // 注意:对args进行操作之前需要进行为空的判断,因为有的方法不带参数,不进行判断,会抛出NullPointerException
        if (args != null){
            for (Object arg : args) {
                System.out.println(" " + arg);
            }
        }
        Object result = method.invoke(target, args);
        System.out.println("After the function");
        return result;
    }
}

 

测试类:

package com.gaopeng.springboot.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class TestDynamicProxy {

    public static void main(String[] args) {
        // 创建一个实例对象,这个对象是被代理的对象
        Person zhangsan = new Student("张三");

        // 创建一个与代理对象相关联的InvocationHandler
        InvocationHandler stuHandler = new StuInvocationHandler(zhangsan);

        // 创建一个代理对象stuProxy来代理zhangsan,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
        // 注意Proxy.newProxyInstance()方法接受三个参数:
        // •ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的
        // •Class<?>[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型
        // •InvocationHandler:指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法
        Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(),
                // Or zhangsan.getClass().getInterfaces(),
                new Class<?>[] { Person.class }, stuHandler);

        // 代理执行上交班费的方法
        stuProxy.giveMoney();
    }

}

 

运行结果:

技术图片

 

 

 

以上是关于代理模式之JDK动态代理的主要内容,如果未能解决你的问题,请参考以下文章

JDK动态代理[2]----JDK动态代理的底层实现之Proxy源码分析

Java动态代理之JDK实现和CGlib实现

#yyds干货盘点# 设计模式之代理模式:动态代理

设计模式之Jdk动态代理

设计模式之代理模式详解和应用

设计模式之JDK动态代理源码分析