1 前言
本节我们讲一下动态代理的实现过程,并且从源码分析下产生过程。看之前先简单看几个基础知识:
- 函数接口BiFunction<T, U, R> : R apply(T t, U u); 就是参数是T、U返回一个结果R 比如: (s1, s2) -> s1.toString() + s2.toString();
- 函数接口Supplier<T> : T get(); 就是参数空返回一个结果T 比如:() -> "1"
- Map res = map.putIfAbsent(key, val) 当key存在,返回对应的值,当key不存在将键值对key->val放进集合,并返回val
- ReferenceQueue 引用队列跟GC相关的一个队列
2 基础使用
JDK的动态代理中有两个主要的类是:InvocationHandler(接口)和Proxy(类):
- InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口,每一个proxy代理实例都有一个关联的调用处理程序;在代理实例调用方法时,方法调用被编码分派到调用处理程序的invoke方法。
- Proxy类就是用来创建一个代理对象的类,它提供了很多方法,比如newProxyInstance。
JDK动态代理步骤:
- 创建被代理的接口和类 也就是我们第一节里的UserService、UserServiceImpl;
- 创建InvocationHandler接口的实现类,在invoke方法中实现代理逻辑;
- 通过Proxy的静态方法newProxyInstance( ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理对象;
- 使用代理对象,完成业务功能。
我们先从一个Demo入手,看一下JDK动态代理的基础用法:
public class MyInvocationHandler implements InvocationHandler { // 被代理的对象 private Object target; public MyInvocationHandler(Object target) { this.target = target; } /** * proxy: 代理类代理的真实代理对象com.sun.proxy.$Proxy0 * method: 我们所要调用某个对象真实的方法的Method对象 * args: 指代代理对象方法传递的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我是前"); Object res = method.invoke(target, args); System.out.println("我是后"); return res; } }
public class Client { public static void main(String[] args) { UserService userService = new UserServiceImpl(); MyInvocationHandler myInvocationHandler = new MyInvocationHandler(userService); /* * newProxyInstance需要的三个参数 * 类加载器、接口数组、InvocationHandler实现 */ UserService proxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), myInvocationHandler); proxy.addUser(); } }
JDK动态代理测试结果:
3 源码解析
通过基础使用,我们发现Proxy返回的代理对象确实对我们的方法进行了增强,那么我们就来看一下代理的创建过程,我们就从Proxy.newProxyInstance出发看起。
3.1 Proxy.newProxyInstance
标签:JDK,Object,代理,InvocationHandler,Proxy,源码,proxy From: https://www.cnblogs.com/kukuxjx/p/17138172.html