优化JDK动态代理

master
linlei 2024-04-11 13:55:28 +08:00
parent 47b58363f9
commit a97d034d98
1 changed files with 10 additions and 43 deletions

View File

@ -2,42 +2,22 @@
- [JDK动态代理](#jdk动态代理) - [JDK动态代理](#jdk动态代理)
- [一、基本信息](#一基本信息) - [一、基本信息](#一基本信息)
- [二、知识储备](#二知识储备) - [二、基本描述](#二基本描述)
- [三、基本描述](#三基本描述) - [三、主要功能](#三主要功能)
- [四、主要功能](#四主要功能) - [四、最佳实践](#四最佳实践)
- [五、最佳实践](#五最佳实践) - [五、源码分析](#五源码分析)
- [六、源码分析](#六源码分析) - [六、常见问题](#六常见问题)
- [七、与其他组件的关系](#七与其他组件的关系)
- [八、常见问题](#八常见问题)
### 一、基本信息 ### 一、基本信息
✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading) ✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
### 二、知识储备 ### 二、基本描述
1. **反射**
+ JDK 动态代理是基于 Java 的反射机制实现的。你需要了解如何在运行时获取类的信息、调用类的方法以及创建对象等。这是因为动态代理是在运行时生成代理类的字节码,并通过反射来实现对方法的调用。
2. **设计模式**
+ 尤其是代理模式。理解代理模式是非常重要的,因为动态代理实际上是代理模式的一种实现。你需要理解代理模式的结构以及它的应用场景。
3. **InvocationHandler**
+ 这是 JDK 动态代理中的核心接口,它用于处理代理对象的方法调用。我们需要了解如何实现 InvocationHandler 接口以及如何在其 invoke 方法中编写代码来处理代理方法的调用。
4. **类加载器**
+ 了解类加载器的工作原理对于理解动态代理的生成过程是很有帮助的。动态代理通过类加载器加载动态生成的代理类,因此我们需要了解类加载器的概念和工作原理。
### 三、基本描述
JDK动态代理是一种在运行时生成代理类的机制它基于接口实现通过在代理类中重定向方法调用到实际对象并提供了InvocationHandler接口来实现代理对象方法调用的处理逻辑适用于AOP、远程方法调用等场景能够在不修改原始类的情况下实现横切关注点的统一管理提供更灵活和可维护的代码结构。 JDK动态代理是一种在运行时生成代理类的机制它基于接口实现通过在代理类中重定向方法调用到实际对象并提供了InvocationHandler接口来实现代理对象方法调用的处理逻辑适用于AOP、远程方法调用等场景能够在不修改原始类的情况下实现横切关注点的统一管理提供更灵活和可维护的代码结构。
### 、主要功能 ### 三、主要功能
1. **代理对象生成** 1. **代理对象生成**
@ -59,7 +39,7 @@ JDK动态代理是一种在运行时生成代理类的机制它基于接口
+ 动态代理是AOP面向切面编程的基础之一可以通过动态代理实现切面的横切关注点将应用程序核心业务逻辑与横切关注点分离开来提高了代码的可维护性和灵活性。 + 动态代理是AOP面向切面编程的基础之一可以通过动态代理实现切面的横切关注点将应用程序核心业务逻辑与横切关注点分离开来提高了代码的可维护性和灵活性。
### 、最佳实践 ### 、最佳实践
使用 JDK 动态代理的基本流程。首先,创建目标对象 `MyService` 的实例,然后获取目标对象的类信息。接着,通过调用 `Proxy.newProxyInstance` 方法创建代理对象,传入目标对象的类加载器、实现的接口以及调用处理器。最后,通过代理对象调用方法,实际上会调用 `MyInvocationHandler` 中的 `invoke` 方法来处理方法调用,并在方法执行前后添加额外的逻辑。 使用 JDK 动态代理的基本流程。首先,创建目标对象 `MyService` 的实例,然后获取目标对象的类信息。接着,通过调用 `Proxy.newProxyInstance` 方法创建代理对象,传入目标对象的类加载器、实现的接口以及调用处理器。最后,通过代理对象调用方法,实际上会调用 `MyInvocationHandler` 中的 `invoke` 方法来处理方法调用,并在方法执行前后添加额外的逻辑。
@ -127,7 +107,7 @@ hello world
After method execution After method execution
``` ```
### 、源码分析 ### 、源码分析
这段代码是通过 Arthas 工具反编译得到的结果。它是一个代理类,位于 `com.sun.proxy` 包下,命名为 `$Proxy0`。该类继承自 `Proxy` 类,并实现了 `MyService` 接口。在 `doSomething` 方法中,通过 `InvocationHandler` 对象的 `invoke` 方法调用了目标对象的 `doSomething` 方法。在静态代码块中,获取了 `java.lang.Object` 类中的 `equals`、`hashCode` 和 `toString` 方法,以及 `MyService` 接口中的 `doSomething` 方法的 `Method` 对象。 这段代码是通过 Arthas 工具反编译得到的结果。它是一个代理类,位于 `com.sun.proxy` 包下,命名为 `$Proxy0`。该类继承自 `Proxy` 类,并实现了 `MyService` 接口。在 `doSomething` 方法中,通过 `InvocationHandler` 对象的 `invoke` 方法调用了目标对象的 `doSomething` 方法。在静态代码块中,获取了 `java.lang.Object` 类中的 `equals`、`hashCode` 和 `toString` 方法,以及 `MyService` 接口中的 `doSomething` 方法的 `Method` 对象。
@ -186,20 +166,7 @@ public final class $Proxy0 extends Proxy implements MyService {
} }
``` ```
### 七、与其他组件的关系 ### 六、常见问题
1. **接口实现关系**
+ JDK动态代理通常基于接口实现。在使用动态代理时需要传入一个接口类型作为参数代理对象会实现这个接口并且在运行时生成的代理类会实现该接口定义的所有方法。因此与其他组件接口的关系是通过实现这些接口来实现的。
2. **代理类关系**
+ JDK动态代理生成的代理类是在运行时动态生成的。这些代理类继承自`Proxy`类,并且实现了传入的接口。因此,代理类与其他组件接口的关系体现在代理类实现了这些接口,从而拥有了对应接口定义的方法。
3. **调用处理器关系**
+ 在使用JDK动态代理时需要提供一个调用处理器`InvocationHandler`)来处理方法调用。该调用处理器可以是自定义的类,它与其他组件接口或类的关系取决于在其`invoke`方法中对方法调用的处理逻辑。
### 八、常见问题
1. **代理对象的类型限制** 1. **代理对象的类型限制**