码迷,mamicode.com
首页 > 其他好文 > 详细

代理模式之JDK动态代理

时间:2019-11-22 13:57:30      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:name   类加载器   cep   function   动态   tcl   ade   private   cat   

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

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动态代理

标签:name   类加载器   cep   function   动态   tcl   ade   private   cat   

原文地址:https://www.cnblogs.com/gaopengpy/p/11910751.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!