0 前言
-
最近在看设计模式的时候,看到了动态代理,觉得动态代理还是挺神奇挺有趣的,于是决定自己动手写写 demo,看看他的实现过程和原理。本文主要是介绍一下 JDK 动态代理,那么废话少说,发车!
1 何为代理
-
举个栗子,你准备自己到楼下去买咖啡,但是这时候突然有事走不开,你就让你的同事帮你买咖啡(顺便请他喝一杯hhh),因此你的同事就是代理类,你就是被代理类,而买咖啡这个行为就是你们需要执行的。
-
正式一点的描述:JDK 动态代理是基于 Java 反射机制实现的,通过实现接口的方式动态创建对象。
2 具体实现
-
定义一个功能接口(买咖啡)
/**
* @Author Jasper
* @Time 2024/01/22
*/
public interface BuyCoffeeService {
void buyCoffee();
}
-
被代理对象(实现类)
/**
* @Author Jasper
* @Time 2024/01/22
*/
public class BuyCoffeeServiceImpl implements BuyCoffeeService {
@Override
public void buyCoffee() {
System.out.println("到楼下买咖啡!");
}
}
-
创建一个 JDK 动态代理处理器,实现 InvocationHandler 接口,重写
invoke()
方法
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* JDK动态代理处理器,需要实现 InvocationHandler接口
* @Author Jasper
* @Time 2024/01/22
*/
public class JdkProxyHandler implements InvocationHandler {
/** 代理目标对象 */
private Object target;
public JdkProxyHandler(Object target){
this.target = target;
}
/**
* Proxy.newProxyInstance()方法的三个参数依次是:
* 1.代理类的类加载器
* 2.实现的所有接口数组
* 3.调用处理器的实现类
*/
@SuppressWarnings("unchecked")
public <T> T getInstance(){
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* 对代理对象进行增强
* @param proxy 代理实例
* @param method 目标对象的方法
* @param args 目标对象的方法需要的参数
* @return 返回调用目标对象方法的结果,是一个Object类型
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入JDK动态代理...");
Object invoke = method.invoke(target, args);
System.out.println("JDK动态代理结束...");
return invoke;
}
}
-
测试类:
/**
* @Author Jasper
* @Time 2024/01/22
*/
public class TestJdkProxy {
public static void main(String[] args) {
// 创建接口实现类,也即被代理的对象
BuyCoffeeServiceImpl buyCoffeeService = new BuyCoffeeServiceImpl();
// 把被代理对象传入,通过Proxy的静态方法newProxyInstance()创建一个代理对象
JdkProxyHandler jdkProxyHandler = new JdkProxyHandler(buyCoffeeService);
BuyCoffeeService instance = jdkProxyHandler.getInstance();
instance.buyCoffee();
}
}
/**
输出结果:
进入JDK动态代理...
到楼下买咖啡!
JDK动态代理结束...
*/
3 原理分析
-
InvocationHandler 为真实对象的方法调用处理器,重写 invoke() 方法目的是:代理方法 buyCoffee() 的调用会委托给 super 类中的 InvocationHandler 对象的 invoke() 方法执行,也正是我们自定义的 JdkProxyHandler 的 invoke() 方法
4 总结
-
JDK 的动态代理步骤:
1、创建接口,定义目标类要完成的功能
2、创建目标类实现该接口
3、创建 InvocationHandler 接口的实现类,在 invoke() 方法中完成代理类的功能(调用目标方法,增强功能)
4、使用 Proxy 类的静态方法 newProxyInstance(),创建代理对象
5、通过代理对象,执行目标方法
-
JDK 动态代理就到此为止啦,后续再聊聊 CGLIB 的动态代理,如有错误,欢迎指正。
-
创作不易,感谢阅读,若遇到问题,可以关注此微信公众号留言反馈,希望能够帮助到您。
原文始发于微信公众号(EzCoding):聊一聊 JDK 动态代理
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/203653.html