From 72e2fe4bded51c7ee8efb1bad66ba5d6c793113e Mon Sep 17 00:00:00 2001
From: 01Petard <1520394133@qq.com>
Date: Thu, 14 Nov 2024 16:49:17 +0800
Subject: [PATCH] =?UTF-8?q?doc:=201=E3=80=81=E4=BF=AE=E6=94=B9=E4=BA=86?=
=?UTF-8?q?=E4=B8=80=E4=BA=9B=E9=94=99=E8=AF=AF=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...a Guide - Java\345\237\272\347\241\200.md" | 200 ++++++++++++++++++
... Java Guide - \351\241\271\347\233\256.md" | 2 +-
2 files changed, 201 insertions(+), 1 deletion(-)
diff --git "a/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - Java\345\237\272\347\241\200.md" "b/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - Java\345\237\272\347\241\200.md"
index 5661ec9..b9c9538 100644
--- "a/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - Java\345\237\272\347\241\200.md"
+++ "b/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - Java\345\237\272\347\241\200.md"
@@ -180,6 +180,206 @@ Java支持数据类型分为两类: 基本数据类型和引用数据类型。
- 许多 Java 框架(如 Hibernate, Spring AOP)使用字节码增强技术,通过修改类的字节码来实现功能增强。常用工具包括 ASM、Javassist、CGLIB 等。
+# CGLib代理
+
+CGLib 广泛用于AOP(面向切面编程)、动态代理等场景。CGLib通过继承的方式在运行时动态生成子类,以实现对目标对象的方法拦截和增强。下面是一些使用CGLib的基本步骤和示例代码。
+
+CGLib是一个非常强大的工具,适用于需要在运行时动态生成类和方法的场景。通过以下步骤,可以轻松地在你的项目中使用CGLib来实现方法拦截和增强。
+
+## 注意事项
+
+- **性能**:虽然CGLib在大多数情况下性能较好,但在高并发场景下,仍然需要注意性能开销。
+- **最终类和方法**:CGLib不能为`final`类或`final`方法生成代理,因为它们不能被继承。
+- **私有方法**:CGLib也不能拦截私有方法,因为子类无法访问父类的私有方法。
+
+## 1. 引入依赖
+
+首先,你需要在你的项目中引入CGLib的依赖。如果你使用Maven,可以在`pom.xml`文件中添加如下依赖:
+
+```xml
+
+ cglib
+ cglib
+ 3.3.0
+
+```
+
+## 2. 定义目标类
+
+假设我们有一个简单的类,我们希望在它的方法调用前后添加一些额外的逻辑。
+
+```java
+public class MyService {
+ public void doSomething() {
+ System.out.println("Doing something...");
+ }
+}
+```
+
+## 3. 创建MethodInterceptor
+
+CGLib的核心接口是`MethodInterceptor`,它允许我们在方法调用时进行拦截。
+
+```java
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+import java.lang.reflect.Method;
+
+public class MyMethodInterceptor implements MethodInterceptor {
+ @Override
+ public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
+ System.out.println("Before method: " + method.getName());
+
+ // 调用原始方法
+ Object result = proxy.invokeSuper(obj, args);
+
+ System.out.println("After method: " + method.getName());
+
+ return result;
+ }
+}
+```
+
+## 4. 创建代理对象
+
+使用CGLib的`Enhancer`类来创建目标类的子类,并将`MethodInterceptor`设置为回调。
+
+```java
+import net.sf.cglib.proxy.Enhancer;
+
+public class CglibExample {
+ public static void main(String[] args) {
+ // 创建Enhancer对象
+ Enhancer enhancer = new Enhancer();
+
+ // 设置目标类
+ enhancer.setSuperclass(MyService.class);
+
+ // 设置回调方法
+ enhancer.setCallback(new MyMethodInterceptor());
+
+ // 创建代理对象
+ MyService myService = (MyService) enhancer.create();
+
+ // 调用方法
+ myService.doSomething();
+ }
+}
+```
+
+## 5. 运行结果
+
+运行上述代码后,输出将会是:
+
+```java
+Before method: doSomething
+Doing something...
+After method: doSomething
+```
+
+# JDK 代理
+
+## 注意事项
+
+- **接口限制**:JDK 动态代理只能为实现了接口的类生成代理对象,如果类没有实现任何接口,则无法使用 JDK 动态代理。
+- **性能**:JDK 动态代理的性能相对较高,但在高并发场景下,仍然需要注意性能开销。
+- **灵活性**:JDK 动态代理基于接口,因此在设计时需要考虑接口的使用。
+
+Java 自带的动态代理机制主要通过 `java.lang.reflect.Proxy` 类和 `java.lang.reflect.InvocationHandler` 接口来实现。这种代理方式主要用于接口的代理,即只能为实现了某个接口的类生成代理对象。下面是一个详细的示例,展示如何使用 JDK 自带的动态代理。
+
+JDK 自带的动态代理机制是一种简单且强大的工具,适用于需要在运行时动态生成代理对象的场景。通过以下步骤,可以轻松地在你的项目中使用 JDK 动态代理来实现方法拦截和增强。
+
+## 1. 定义接口和目标类
+
+首先,定义一个接口,这个接口将由目标类和代理类共同实现。
+
+```java
+public interface MyService {
+ void doSomething();
+}
+```
+
+实现上述接口的目标类。
+
+```java
+public class MyServiceImpl implements MyService {
+ @Override
+ public void doSomething() {
+ System.out.println("Doing something...");
+ }
+}
+```
+
+## 2. 创建InvocationHandler
+
+实现 `InvocationHandler` 接口,这个接口的 `invoke` 方法将在代理对象的方法被调用时执行。
+
+```java
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+public class MyInvocationHandler implements InvocationHandler {
+ private final MyService target;
+
+ public MyInvocationHandler(MyService target) {
+ this.target = target;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ System.out.println("Before method: " + method.getName());
+
+ // 调用目标对象的方法
+ Object result = method.invoke(target, args);
+
+ System.out.println("After method: " + method.getName());
+
+ return result;
+ }
+}
+```
+
+## 3. 创建代理对象
+
+使用 `Proxy.newProxyInstance` 方法创建代理对象。
+
+```java
+import java.lang.reflect.Proxy;
+
+public class JdkProxyExample {
+ public static void main(String[] args) {
+ // 创建目标对象
+ MyService target = new MyServiceImpl();
+
+ // 创建InvocationHandler
+ MyInvocationHandler handler = new MyInvocationHandler(target);
+
+ // 创建代理对象
+ MyService proxy = (MyService) Proxy.newProxyInstance(
+ target.getClass().getClassLoader(), // 类加载器
+ target.getClass().getInterfaces(), // 目标类实现的接口
+ handler // InvocationHandler
+ );
+
+ // 调用代理对象的方法
+ proxy.doSomething();
+ }
+}
+```
+
+## 4. 运行结果
+
+运行上述代码后,输出将会是:
+
+深色版本
+
+```java
+Before method: doSomething
+Doing something...
+After method: doSomething
+```
+
#
------------------设计模式------------------
# 为什么要用设计模式?
diff --git "a/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - \351\241\271\347\233\256.md" "b/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - \351\241\271\347\233\256.md"
index 010e466..ebf3a94 100644
--- "a/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - \351\241\271\347\233\256.md"
+++ "b/docs/\345\274\200\345\217\221/My Java Guide/My Java Guide - \351\241\271\347\233\256.md"
@@ -104,7 +104,7 @@ top_img: /img/Java-tutorials-by-GeeksForGeeks.png
**2.1 请求幂等性**
-? 确保同一个请求多次执行的结果相同,不会重复执行某些操作,如:
+确保同一个请求多次执行的结果相同,不会重复执行某些操作,如:
- **唯一标识**:为每个请求分配一个唯一的标识符(如订单号),在处理请求时先检查该标识符是否存在。
- **状态码**:使用 HTTP 状态码来表示请求的幂等性,如 `201 Created` 表示资源已被创建,后续请求可以直接返回 `200 OK` 而不需要再次创建。