From ea493390a63e22e8a0abea4ad77b189fff3a2a1b Mon Sep 17 00:00:00 2001 From: whai Date: Mon, 11 Nov 2024 13:47:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(SpringDemo):=20=E6=B7=BB=E5=8A=A0=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E9=87=8D=E8=AF=95=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增重试相关的异常类和枚举类型- 实现重试切面,支持接口级别的重试限制 - 添加重试控制器和相关注解 - 修改数据库连接配置,启用SSL Changes application.yaml AppTest.java AppTest.java BockingQueueDemo.java BuinessException.java DelayQueueDemo.java ErrorType.java FunctionInterfaceDemo.java FutureRelative.java LCR155.java LCR186.java LeetCod42_1.java LeetCode15.java LeetCode45.java LeetCode48.java LeetCode51.java LeetCode392.java LeetCode494.java LeetCode718.java LeetCode_32.java P1.java pom.xml pom.xml pom.xml pom.xml RetryAspect.java RetryController.java RetryLimit.java sadasf.bpmn20.xml sdoih.bpmn SpringDemoApplication.java workflow.md Unversioned Files C:\Users\wenhai\project\javaProject\LeetCode\Activiti7Demo\.gitignore C:\Users\wenhai\project\javaProject\LeetCode\Activiti7Demo\src\main\java\cn\whai\activiti\Activiti7DemoApplication.java C:\Users\wenhai\project\javaProject\LeetCode\Activiti7Demo\src\test\java\cn\whai\activiti\activiti7demo\Activiti7DemoApplicationTests.java C:\Users\wenhai\project\javaProject\LeetCode\Activiti7Demo\src\main\resources\application.yaml C:\Users\wenhai\project\javaProject\LeetCode\Activiti7Demo\pom.xml --- Activiti7Demo/.gitignore | 33 ++++ Activiti7Demo/pom.xml | 80 ++++++++++ .../activiti/Activiti7DemoApplication.java | 19 +++ .../src/main/resources/application.yaml | 18 +++ .../src/main/resources/sadasf.bpmn20.xml | 48 ++++++ .../Activiti7DemoApplicationTests.java | 24 +++ Activiti7Demo/workflow.md | 57 +++++++ ForJdk17/pom.xml | 2 +- .../java/cn/whaifree/interview/js/P1.java | 83 ++++++++++ .../whaifree/redo/redo_all_241016/LCR155.java | 66 ++++++++ .../whaifree/redo/redo_all_241016/LCR186.java | 34 ++++ .../redo/redo_all_241016/LeetCod42_1.java | 52 +++++++ .../redo/redo_all_241016/LeetCode15.java | 60 +++++++ .../redo/redo_all_241016/LeetCode392.java | 76 +++++++++ .../redo/redo_all_241016/LeetCode45.java | 83 ++++++++++ .../redo/redo_all_241016/LeetCode48.java | 28 ++++ .../redo/redo_all_241016/LeetCode494.java | 71 +++++++++ .../redo/redo_all_241016/LeetCode51.java | 87 +++++++++++ .../redo/redo_all_241016/LeetCode718.java | 52 +++++++ .../redo/redo_all_241016/LeetCode_32.java | 54 +++++++ .../cn/whaifree/tech/BockingQueueDemo.java | 45 ++++++ .../tech/demo/thread/DelayQueueDemo.java | 16 ++ .../tech/demo/thread/FutureRelative.java | 7 +- .../src/test/java/org/example/AppTest.java | 2 +- ForJdk8/pom.xml | 2 +- .../whaifree/tech/FunctionInterfaceDemo.java | 1 + .../src/test/java/org/example/AppTest.java | 2 +- SeleniumDemo/pom.xml | 2 +- .../springdemo/SpringDemoApplication.java | 2 + .../interceptRetry/BuinessException.java | 22 +++ .../controller/interceptRetry/ErrorType.java | 18 +++ .../interceptRetry/RetryController.java | 24 +++ .../interceptRetry/aspect/RetryAspect.java | 146 ++++++++++++++++++ .../interceptRetry/aspect/RetryLimit.java | 26 ++++ .../src/main/resources/application.yaml | 2 +- pom.xml | 4 +- sdoih.bpmn | 2 + 37 files changed, 1341 insertions(+), 9 deletions(-) create mode 100644 Activiti7Demo/.gitignore create mode 100644 Activiti7Demo/pom.xml create mode 100644 Activiti7Demo/src/main/java/cn/whai/activiti/Activiti7DemoApplication.java create mode 100644 Activiti7Demo/src/main/resources/application.yaml create mode 100644 Activiti7Demo/src/main/resources/sadasf.bpmn20.xml create mode 100644 Activiti7Demo/src/test/java/cn/whai/activiti/activiti7demo/Activiti7DemoApplicationTests.java create mode 100644 Activiti7Demo/workflow.md create mode 100644 ForJdk17/src/main/java/cn/whaifree/interview/js/P1.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LCR155.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LCR186.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCod42_1.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode15.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode392.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode45.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode48.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode494.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode51.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode718.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode_32.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/tech/BockingQueueDemo.java create mode 100644 ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/DelayQueueDemo.java create mode 100644 SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/BuinessException.java create mode 100644 SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/ErrorType.java create mode 100644 SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/RetryController.java create mode 100644 SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryAspect.java create mode 100644 SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryLimit.java create mode 100644 sdoih.bpmn diff --git a/Activiti7Demo/.gitignore b/Activiti7Demo/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/Activiti7Demo/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/Activiti7Demo/pom.xml b/Activiti7Demo/pom.xml new file mode 100644 index 0000000..7c18bb6 --- /dev/null +++ b/Activiti7Demo/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.5.5 + + + cn.whai.activiti + Activiti7Demo + 0.0.1-SNAPSHOT + Activiti7Demo + Activiti7Demo Springboot + + 1.8 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.projectlombok + lombok + + + org.springframework.boot + spring-boot-starter-test + + + + + org.activiti + activiti-spring-boot-starter + 7.0.0.GA + + + + org.mybatis + mybatis + + + + + + + mysql + mysql-connector-java + + + + + com.baomidou + mybatis-plus-boot-starter + 3.4.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + + diff --git a/Activiti7Demo/src/main/java/cn/whai/activiti/Activiti7DemoApplication.java b/Activiti7Demo/src/main/java/cn/whai/activiti/Activiti7DemoApplication.java new file mode 100644 index 0000000..df1f2b1 --- /dev/null +++ b/Activiti7Demo/src/main/java/cn/whai/activiti/Activiti7DemoApplication.java @@ -0,0 +1,19 @@ +package cn.whai.activiti; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication(exclude = { + //activiti 默认整合security,屏蔽Security认证 + SecurityAutoConfiguration.class, + ManagementWebSecurityAutoConfiguration.class +}) +public class Activiti7DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(Activiti7DemoApplication.class, args); + } + +} diff --git a/Activiti7Demo/src/main/resources/application.yaml b/Activiti7Demo/src/main/resources/application.yaml new file mode 100644 index 0000000..486fe34 --- /dev/null +++ b/Activiti7Demo/src/main/resources/application.yaml @@ -0,0 +1,18 @@ +server: + port: 18080 + +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/activiti?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai + username: root + password: 123456 + activiti: + db-history-used: true + history-level: full + database-schema-update: true + check-process-definitions: false + +mybatis-plus: + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl diff --git a/Activiti7Demo/src/main/resources/sadasf.bpmn20.xml b/Activiti7Demo/src/main/resources/sadasf.bpmn20.xml new file mode 100644 index 0000000..47d2c78 --- /dev/null +++ b/Activiti7Demo/src/main/resources/sadasf.bpmn20.xml @@ -0,0 +1,48 @@ + + + + + + SequenceFlow_1 + + + SequenceFlow_1 + SequenceFlow_2 + + + SequenceFlow_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Activiti7Demo/src/test/java/cn/whai/activiti/activiti7demo/Activiti7DemoApplicationTests.java b/Activiti7Demo/src/test/java/cn/whai/activiti/activiti7demo/Activiti7DemoApplicationTests.java new file mode 100644 index 0000000..6710353 --- /dev/null +++ b/Activiti7Demo/src/test/java/cn/whai/activiti/activiti7demo/Activiti7DemoApplicationTests.java @@ -0,0 +1,24 @@ +package cn.whai.activiti.activiti7demo; + + +import org.activiti.engine.ProcessEngine; +import org.activiti.engine.ProcessEngineConfiguration; +import org.activiti.engine.RepositoryService; +import org.activiti.spring.SpringProcessEngineConfiguration; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@SpringBootTest +class Activiti7DemoApplicationTests { + + + + @Test + void contextLoads() { + + } + +} diff --git a/Activiti7Demo/workflow.md b/Activiti7Demo/workflow.md new file mode 100644 index 0000000..42b2621 --- /dev/null +++ b/Activiti7Demo/workflow.md @@ -0,0 +1,57 @@ +## WordFlow 工作流引擎 + +是一种按照预定义规则【需要符合BPMN规范】进行部署,将业务和节点的流程进行分离【特定形式进行关联】, + + +### 二、什么是Activiti7? + +Activiti 是一个工作流引擎, activiti 可以将业务系统中复杂的业务流程抽取出来,使用专门的 +建模语言(BPMN2.0)进行定义,业务系统按照预先定义的流程进行执行 + +https://www.activiti.org + +2.2 Activiti7内部核心机制 + +1️⃣业务流程图要规范化,需要遵守一套标准。 + +2️⃣业务流程图本质上就是一个XML文件,而XML可以存放所要的数据。 + +3️⃣读取业务流程图的过程就是解析XML文件的过程。 + +4️⃣读取一个业务流程图的结点就相当于解析一个XML的结点,进一步将数据插入到MySQL表中,形成一条记录。 + +5️⃣将一个业务流程图的所有节点都读取并存入到MySQL表中。 + +6️⃣后面只要读取MySQL表中的记录就相当于读取业务流程图的一个节点。 + +7️⃣业务流程的推进,后面就转换为读取表中的数据,并且处理数据,结束的时候这一行数据就可以删除了。 + +### BPMN + +BPMN(Business Process Model And Notation),业务流程模型和符号,是由BPMI(Business Process Management Initiative)开发的一套的业务流程建模符号,使用BPMN提供的符号可以创建业务流程。2004年5月发布了BPMN1.0规范。 + +> [processOn BPMN 概念](https://www.processon.com/knowledge/bpmndiagram) +> +> ### BPMN 的核心元素 +> - 活动:活动是 BPMN 中最基本的元素之一,它代表了业务流程中的一个具体任务或操作。可以自动/手动、 +> - 事件:事件是 BPMN 中用于表示流程中的特定时刻或状态的元素。例如,开始事件、结束事件、中间事件等。 +> - 网关:网关用于控制流程的执行路径,可以实现并行、条件、互斥等多种逻辑。 +> - 泳道:泳道用于将流程分解为多个并行的部分,每个泳道代表一个独立的执行路径。 + +> 一个BPMN的例子: +> - 当事人填写请假单,启动流程后把请假单ID绑定到流程中; +> - 部门经理对请假单进行审核; +> - 然后人事经理进行复核并进行备案; +> - 最后请假流程结束。 + +### Activiti支持的数据库 + +- Activiti的运行需要数据库的支撑,支持如下: + - h2 + - MySQL + - Oracle + - Db2 + - postgres + - mysql + +- 在Navicat工具中创建`activiti`的数据库,用于后续的实验. diff --git a/ForJdk17/pom.xml b/ForJdk17/pom.xml index 90589fb..fe7a977 100644 --- a/ForJdk17/pom.xml +++ b/ForJdk17/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.whai LeetCode 1.0-SNAPSHOT diff --git a/ForJdk17/src/main/java/cn/whaifree/interview/js/P1.java b/ForJdk17/src/main/java/cn/whaifree/interview/js/P1.java new file mode 100644 index 0000000..48c44ed --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/interview/js/P1.java @@ -0,0 +1,83 @@ +package cn.whaifree.interview.js; + +import java.util.*; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/10 19:27 + * @注释 + */ +public class P1 { + + public static void main(String[] args) { + + System.out.println(Arrays.toString(new P1().solve(new int[]{2,3,2,3,2}))); + } + + /** + * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 + * + * + * @param arr int整型一维数组 + * @return int整型一维数组 + */ + public int[] solve (int[] arr) { + // write code here + + Map> map = new HashMap<>(); + for (int i = 0; i < arr.length; i++) { + if (!map.containsKey(arr[i])) { + map.put(arr[i], new ArrayList<>()); + } + map.get(arr[i]).add(i + 1); + } + + int[] res = new int[arr.length]; + for (Map.Entry> entry : map.entrySet()) { + List value = entry.getValue(); + if (value.size() == 2) { + Integer a = value.get(1); + Integer b = value.get(0); + res[b - 1] = a; + res[a - 1] = b; + }else { + for (Integer i : value) { + res[i - 1] = -1; + } + } + } + return res; + } +} + +class p2{ + + public static void main(String[] args) { + System.out.println(new p2().solve(new int[]{1, 2})); + } + /** + * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 + * + * + * @param arr int整型一维数组 + * @return long长整型 + */ + public long solve (int[] arr) { + int n = arr.length; + int[][] dp = new int[n][n]; + for (int len = 2; len <= n; len++) { + for (int i = 0; i <= n - len; i++) { + int j = i + len - 1; + if (arr[i] == arr[j]) { + dp[i][j] = dp[i + 1][j - 1]; + }else { + dp[i][j] = Math.min(dp[i + 1][j], dp[i][j - 1]) + + Math.abs(arr[i] - arr[j]); + } + } + } + int i = dp[0][n - 1]; + return i; + } +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LCR155.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LCR155.java new file mode 100644 index 0000000..8296061 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LCR155.java @@ -0,0 +1,66 @@ +package cn.whaifree.redo.redo_all_241016; + +import org.junit.Test; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/9 18:04 + * @注释 + */ +public class LCR155 { + class Node { + public int val; + public Node left; + public Node right; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val,Node _left,Node _right) { + val = _val; + left = _left; + right = _right; + } + } + + @Test + public void test() { + Solution solution = new Solution(); + Node node = new Node(4); + Node node1 = solution.treeToDoublyList(node); + System.out.println(node1); + } + + class Solution { + + Node head = new Node(-1); + Node index = head; + + public Node treeToDoublyList(Node root) { + if (root == null) { + return null; + } + + in(root); + index.right = head.right; + head.right.left = index; + return head.right; + } + + public void in(Node root) { + if (root == null) { + return; + } + in(root.left); + index.right = root; + root.left = index; + index = root; + in(root.right); + } + } + +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LCR186.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LCR186.java new file mode 100644 index 0000000..08452d0 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LCR186.java @@ -0,0 +1,34 @@ +package cn.whaifree.redo.redo_all_241016; + +import java.util.Set; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/9 18:20 + * @注释 + */ +public class LCR186 { + + class Solution { + public boolean checkDynasty(int[] places) { + int[] set = new int[14]; + int min = Integer.MAX_VALUE; + int max = Integer.MIN_VALUE; + for (int i = 0; i < places.length; i++) { + if (places[i] == 0) { + continue; + // 差值为5以内,并且不重复,就能推出这是个顺子 + } + if (set[places[i]] != 0) { + // 已经存在,直接返回 + return false; + } + set[places[i]]++; + min = Math.min(min, places[i]); + max = Math.max(max, places[i]); + } + return max - min < 5; + } + } +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCod42_1.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCod42_1.java new file mode 100644 index 0000000..fe902f2 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCod42_1.java @@ -0,0 +1,52 @@ +package cn.whaifree.redo.redo_all_241016; + +import org.junit.Test; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/11 10:36 + * @注释 + */ +public class LeetCod42_1 { + + @Test + public void test() { + int[] height = {4,2,0,3,2,5}; + int trap = new Solution().trap(height); + System.out.println(trap); + } + + class Solution { + /** + * 每个位置左边第一个比他大的 + * @param height + * @return + */ + public int trap(int[] height) { + Deque stack = new ArrayDeque<>(); + stack.push(0); + int res = 0; + for (int i = 1; i < height.length; i++) { + while (!stack.isEmpty() && height[stack.peek()] < height[i]) { + // 单调递增 + Integer pop = stack.pop(); + int level = height[pop]; + if (!stack.isEmpty()) { + int left = stack.peek(); + int right = i; + int sub = Math.min(height[left], height[right]) - level; + res += sub * (right - left - 1); + } + } + stack.push(i); + } + + return res; + } + } + +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode15.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode15.java new file mode 100644 index 0000000..ba31417 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode15.java @@ -0,0 +1,60 @@ +package cn.whaifree.redo.redo_all_241016; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/6 13:20 + * @注释 + */ +public class LeetCode15 { + + @Test + public void test() { + int[] nums = {1,2,-2,-1}; + System.out.println(new Solution().threeSum(nums)); + } + + class Solution { + + public List> threeSum(int[] nums) { + Arrays.sort(nums); + List> res = new ArrayList<>(); + for (int left = 0; left < nums.length; left++) { + + if (left > 0 && nums[left] == nums[left - 1]) { + continue; + } + + int mid = left + 1; + int right = nums.length - 1; + while (mid < right) { + int sum = nums[left] + nums[mid] + nums[right]; + if (sum == 0) { + res.add(Arrays.asList(nums[left], nums[mid], nums[right])); + + while (mid < right && nums[mid] == nums[mid + 1]) { + mid++; + } + while (mid < right && nums[right] == nums[right - 1]) { + right--; + } + mid++; + right--; + } else if (sum < 0) { + mid++; + } else { + right--; + } + } + } + return res; + } + } + +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode392.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode392.java new file mode 100644 index 0000000..f913df4 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode392.java @@ -0,0 +1,76 @@ +package cn.whaifree.redo.redo_all_241016; + +import org.junit.Test; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/8 17:22 + * @注释 + */ +public class LeetCode392 { + + @Test + public void test() { + System.out.println(new Solution().isSubsequence("abc", "ahbgdc")); + } + + class Solution { + public boolean isSubsequence(String s, String t) { + if (s.isBlank()) { + return true; + } + + int sIndex = 0; + int i = 0; + for (; i < t.length(); i++) { + if (sIndex == s.length()) { + break; + } + if (s.charAt(sIndex) == t.charAt(i)) { + sIndex++; + } + } + return sIndex == s.length(); + } + + } + @Test + public void test2() { + System.out.println(new Solution1().isSubsequence("abc", "ahbgdc")); + } + + class Solution1 { + /** + * + * ''a h b g d c + * '' 1 1 1 1 1 1 1 + * a 0 1 1 1 1 1 1 + * b 0 0 0 1 1 1 1 + * c 0 0 0 0 0 0 1 + * + * 0-1背包问题, + * @param s + * @param t + * @return + */ + public boolean isSubsequence(String s, String t) { + boolean[][] dp = new boolean[s.length() + 1][t.length() + 1]; + for (int i = 0; i < t.length() + 1; i++) { + dp[0][i] = true; + } + for (int i = 1; i <= s.length(); i++) { + for (int j = 1; j <= t.length(); j++) { + if (s.charAt(i - 1) != t.charAt(j - 1) || !dp[i - 1][j - 1]) { + dp[i][j] = dp[i][j - 1]; + } else { + dp[i][j] = true; + } + } + } + return dp[s.length()][t.length()]; + } + + } + +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode45.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode45.java new file mode 100644 index 0000000..420b16d --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode45.java @@ -0,0 +1,83 @@ +package cn.whaifree.redo.redo_all_241016; + +import org.junit.Test; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/8 19:52 + * @注释 + */ +public class LeetCode45 { + + @Test + public void test() { + int[] nums = {2,3,1,1,4}; + int jump = new Solution().jump(nums); + System.out.println(jump); + } + + class Solution { + /** + * + * @param nums + * @return + */ + public int jump(int[] nums) { + if (nums.length == 1) { + return 0; + } + int curCover = 0; + int maxCover = 0; + int jump = 0; + for (int i = 0; i < nums.length; i++) { + maxCover = Math.max(maxCover, i + nums[i]); + // 如果从这个 起跳点 起跳叫做第 1 次 跳跃, + // 那么从后面 nums[0]个格子起跳 都 可以叫做第 2 次 跳跃。 + if (i == curCover) { + curCover = maxCover; + jump++; + } + if (curCover >= nums.length - 1) { + return jump; + } + } + return jump; + } + } + + @Test + public void test1() { + int[] nums = {2,3,1,1,4}; + int jump = new Solution1().jump(nums); + System.out.println(jump); + } + + class Solution1 { + /** + * [2,3,1,1,4] + * 0 1 1 2 2 + * @param nums + * @return + */ + public int jump(int[] nums) { + if (nums.length == 1) { + return 0; + } + // 动态规划 + int[] dp = new int[nums.length]; + dp[0] = 0; + for (int i = 1; i < nums.length; i++) { + int min = Integer.MAX_VALUE; + for (int j = 0; j < i; j++) { + if (nums[j] >= i - j) { + min = Math.min(min, dp[j] + 1); + } + } + dp[i] = min; + } + return dp[nums.length - 1]; + } + } + +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode48.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode48.java new file mode 100644 index 0000000..707d686 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode48.java @@ -0,0 +1,28 @@ +package cn.whaifree.redo.redo_all_241016; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/6 13:31 + * @注释 + */ +public class LeetCode48 { + + class Solution { + public void rotate(int[][] matrix) { + int len = matrix.length; + for (int i = 0; i < len / 2; i++) { + for (int j = i; j < len; j++) { + int x = i; + int y = j; + int n = len - 1; + int tmp = matrix[x][y]; + matrix[x][y] = matrix[n - y][x]; + matrix[n - y][x] = matrix[n - x][n - y]; + matrix[n - x][n - y] = matrix[y][n - x]; + matrix[y][n - x] = tmp; + } + } + } + } +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode494.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode494.java new file mode 100644 index 0000000..f9cdc90 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode494.java @@ -0,0 +1,71 @@ +package cn.whaifree.redo.redo_all_241016; + +import org.junit.Test; + +import java.util.Arrays; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/10 17:19 + * @注释 + */ +public class LeetCode494 { + + class Solution { + + /** + * 背包问题 + * + * 1 2 1 1 1 ; 3 + * x为需要变成负数的数量 + * + * sum = x * 2 + target + * + * x = sum-target /2 + * + * 把nums里装到容量为x的背包中 + * 有几种方法可以装满 + * + * 0 1 2 3 + * 1 1 1 0 0 + * 2 1 1 1 1 + * 2 1 1 2 2 + * 1 + * 1 + * + * 1 2 -2 1 1 + * 1 2 -2 -1 -1 + * -1 2 -2 1 -1 + * -1 2 -2 -1 1 + * + * + * + * @param nums + * @param target + * @return + */ + public int findTargetSumWays(int[] nums, int target) { + Integer sum = Arrays.stream(nums).sum(); + int pkgSize = (sum - target) / 2; + int[] dp = new int[pkgSize + 1]; + dp[0] = 1; + for (int i = 0; i < nums.length; i++) { + for (int j = pkgSize; j >= 0; j--) { + if (j >= nums[i]) { + dp[j] = dp[j] + dp[j - nums[i]]; + } + } + } + return dp[pkgSize]; + } + } + + @Test + public void test() { + int[] nums = {1}; + int target = 1; + System.out.println(new Solution().findTargetSumWays(nums, target)); + } + +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode51.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode51.java new file mode 100644 index 0000000..0349632 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode51.java @@ -0,0 +1,87 @@ +package cn.whaifree.redo.redo_all_241016; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/8 18:34 + * @注释 + */ +public class LeetCode51 { + + @Test + public void test() { + for (List solveNQueen : new Solution().solveNQueens(4)) { + System.out.println(solveNQueen); + } + } + class Solution { + List> res = new ArrayList<>(); + + public List> solveNQueens(int n) { + char[][] map = new char[n][n]; + for (char[] chars : map) { + Arrays.fill(chars, '.'); + } + backTracking(map, 0); + return res; + } + + public void backTracking(char[][] map, int x) { + if (x == map.length) { + ArrayList e = new ArrayList<>(); + for (char[] chars : map) { + e.add(new String(chars)); + } + res.add(e); + return; + } + if (x > map.length) { + return; + } + for (int i = 0; i < map.length; i++) { + if (cal(map, x, i)) { + map[x][i] = 'Q'; + backTracking(map, x + 1); + map[x][i] = '.'; + } + } + } + + // 往左上搜索 + public boolean cal(char[][] map, int x, int y) { + // 往左边搜索 + for (int i = y; i >= 0; i--) { + if (map[x][i] == 'Q') { + return false; + } + } + // 往上搜索 + for (int i = x; i >= 0; i--) { + if (map[i][y] == 'Q') { + return false; + } + } + + // 往左上搜索 + for (int i = x, j = y; i >= 0 && j >= 0; i--, j--) { + if (map[i][j] == 'Q') { + return false; + } + } + // 往右上搜索 + for (int i = x, j = y; i >= 0 && j < map.length; i--, j++) { + if (map[i][j] == 'Q') { + return false; + } + } + + return true; + } + } +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode718.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode718.java new file mode 100644 index 0000000..2544505 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode718.java @@ -0,0 +1,52 @@ +package cn.whaifree.redo.redo_all_241016; + +import org.junit.Test; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/8 17:16 + * @注释 + */ +public class LeetCode718 { + + @Test + public void test() { + Solution solution = new Solution(); + System.out.println(solution.findLength(new int[]{1, 2, 3, 2, 1, 5, 8, 9}, new int[]{3, 2, 1, 5, 8, 4, 7})); + } + + class Solution { + /** + * 连续 + * 0-i 0-j内最长公共的子数组的长度 + * + * 1 2 3 2 1 + * 3 0 0 1 0 0 + * 2 0 1 0 2 0 + * 1 1 0 1 + * 4 + * 7 + * + * @param nums1 + * @param nums2 + * @return + */ + public int findLength(int[] nums1, int[] nums2) { + + int[][] dp = new int[nums1.length + 1][nums2.length + 1]; + + int max = 0; + for (int i = 1; i <= nums1.length; i++) { + for (int j = 1; j <= nums2.length; j++) { + if (nums1[i - 1] == nums2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + max = Math.max(max, dp[i][j]); + } + } + } + return max; + } + } + +} diff --git a/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode_32.java b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode_32.java new file mode 100644 index 0000000..9df37f9 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/redo/redo_all_241016/LeetCode_32.java @@ -0,0 +1,54 @@ +package cn.whaifree.redo.redo_all_241016; + +import org.junit.Test; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/11 11:36 + * @注释 + */ +public class LeetCode_32 { + + @Test + public void test() { + Solution solution = new Solution(); + System.out.println(solution.longestValidParentheses("(()(()()")); + + } + + class Solution { + public int longestValidParentheses(String s) { + + boolean[] mark = new boolean[s.length()]; + + char[] arr = s.toCharArray(); + Deque stack = new ArrayDeque<>(); + for (int i = 0; i < arr.length; i++) { + if (arr[i] == '(') { + stack.push(i); + } else if (!stack.isEmpty()) { + Integer pop = stack.pop(); + mark[pop] = true; + mark[i] = true; + } + } + + int left = 0; + int right = 0; + int maxLen = 0; + while (right < mark.length) { + if (!mark[right]) { + maxLen = Math.max(maxLen, right - left); + left = right + 1; + } + right++; + } + return Math.max(maxLen, right - left); + } + } + +} diff --git a/ForJdk17/src/main/java/cn/whaifree/tech/BockingQueueDemo.java b/ForJdk17/src/main/java/cn/whaifree/tech/BockingQueueDemo.java new file mode 100644 index 0000000..6840189 --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/tech/BockingQueueDemo.java @@ -0,0 +1,45 @@ +package cn.whaifree.tech; + +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/5 22:22 + * @注释 + */ +public class BockingQueueDemo { + + + static int size = 3; + static List instanceId = List.of(); + static { + for (int i = 0; i < 50; i++) { + instanceId.add("instance" + i); + } + } + + public static void main(String[] args) { + + BlockingQueue queue = new LinkedBlockingQueue<>(); + + new Thread(new Runnable() { + @Override + public void run() { + queue.addAll(instanceId); + } + }).start(); + + new Thread(new Runnable() { + @Override + public void run() { + for (int i = 0; i < size; i++) { + + } + } + }).start(); + } +} diff --git a/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/DelayQueueDemo.java b/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/DelayQueueDemo.java new file mode 100644 index 0000000..bdf698a --- /dev/null +++ b/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/DelayQueueDemo.java @@ -0,0 +1,16 @@ +package cn.whaifree.tech.demo.thread; + +import java.util.concurrent.*; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/5 14:24 + * @注释 + */ +public class DelayQueueDemo { + + public static void main(String[] args) { + + } +} diff --git a/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/FutureRelative.java b/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/FutureRelative.java index 83e71e5..43f69ab 100644 --- a/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/FutureRelative.java +++ b/ForJdk17/src/main/java/cn/whaifree/tech/demo/thread/FutureRelative.java @@ -17,9 +17,14 @@ public class FutureRelative { final static ExecutorService executorService = Executors.newFixedThreadPool(10, Executors.defaultThreadFactory()); + final static ExecutorService executorService1 = Executors.newScheduledThreadPool(10); + + + public static void main(String[] args) { - futureTaskDemo(); + +// futureTaskDemo(); } diff --git a/ForJdk17/src/test/java/org/example/AppTest.java b/ForJdk17/src/test/java/org/example/AppTest.java index d5f435d..da1f544 100644 --- a/ForJdk17/src/test/java/org/example/AppTest.java +++ b/ForJdk17/src/test/java/org/example/AppTest.java @@ -1,4 +1,4 @@ -package org.example; +package com.whai; import junit.framework.Test; import junit.framework.TestCase; diff --git a/ForJdk8/pom.xml b/ForJdk8/pom.xml index bec8e25..343ff14 100644 --- a/ForJdk8/pom.xml +++ b/ForJdk8/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.whai LeetCode 1.0-SNAPSHOT diff --git a/ForJdk8/src/main/java/cn/whaifree/tech/FunctionInterfaceDemo.java b/ForJdk8/src/main/java/cn/whaifree/tech/FunctionInterfaceDemo.java index a0da3cc..72422e6 100644 --- a/ForJdk8/src/main/java/cn/whaifree/tech/FunctionInterfaceDemo.java +++ b/ForJdk8/src/main/java/cn/whaifree/tech/FunctionInterfaceDemo.java @@ -1,6 +1,7 @@ package cn.whaifree.tech; import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantLock; /** diff --git a/ForJdk8/src/test/java/org/example/AppTest.java b/ForJdk8/src/test/java/org/example/AppTest.java index e027d94..d4e2014 100644 --- a/ForJdk8/src/test/java/org/example/AppTest.java +++ b/ForJdk8/src/test/java/org/example/AppTest.java @@ -1,4 +1,4 @@ -package org.example; +package com.whai; import junit.framework.Test; import junit.framework.TestCase; diff --git a/SeleniumDemo/pom.xml b/SeleniumDemo/pom.xml index 25f97ec..c1e3d0a 100644 --- a/SeleniumDemo/pom.xml +++ b/SeleniumDemo/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.whai LeetCode 1.0-SNAPSHOT diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/SpringDemoApplication.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/SpringDemoApplication.java index 8e9b70c..a164470 100644 --- a/SpringDemo/src/main/java/cn/whaifree/springdemo/SpringDemoApplication.java +++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/SpringDemoApplication.java @@ -2,8 +2,10 @@ package cn.whaifree.springdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.EnableAspectJAutoProxy; @SpringBootApplication +@EnableAspectJAutoProxy public class SpringDemoApplication { public static void main(String[] args) { diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/BuinessException.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/BuinessException.java new file mode 100644 index 0000000..d8f93a4 --- /dev/null +++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/BuinessException.java @@ -0,0 +1,22 @@ +package cn.whaifree.springdemo.controller.interceptRetry; + +import lombok.Getter; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/10 15:26 + * @注释 + */ +public class BuinessException extends RuntimeException { + @Getter + private ErrorType type; + private Integer code; + + + public BuinessException(ErrorType type, Integer code) { + this.type = type; + this.code = code; + } +} + diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/ErrorType.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/ErrorType.java new file mode 100644 index 0000000..9040b34 --- /dev/null +++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/ErrorType.java @@ -0,0 +1,18 @@ +package cn.whaifree.springdemo.controller.interceptRetry; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/10 15:26 + * @注释 + */ +public enum ErrorType { + RetryType("Retry Too Many", 503); + + private String type; + private Integer code; + ErrorType (String type, Integer code) { + this.type = type; + this.code = code; + } +} diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/RetryController.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/RetryController.java new file mode 100644 index 0000000..d34b204 --- /dev/null +++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/RetryController.java @@ -0,0 +1,24 @@ +package cn.whaifree.springdemo.controller.interceptRetry; + +import cn.whaifree.springdemo.controller.interceptRetry.aspect.RetryLimit; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/9 21:56 + * @注释 + */ +@RestController +public class RetryController { + + @PostMapping("/try") + @RetryLimit(limitCount = 3, limitTime = 1, limitKey = "ip", resMsg = "retry请求频繁") + public String tryMethod(int success) { + if (success == 1) { + throw new BuinessException(ErrorType.RetryType, 500); + } + return "tryMethod"; + } +} diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryAspect.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryAspect.java new file mode 100644 index 0000000..27640b6 --- /dev/null +++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryAspect.java @@ -0,0 +1,146 @@ +package cn.whaifree.springdemo.controller.interceptRetry.aspect; + +import cn.hutool.core.util.ReflectUtil; +import cn.hutool.extra.servlet.ServletUtil; +import cn.hutool.extra.spring.SpringUtil; +import cn.hutool.http.HttpUtil; +import cn.whaifree.springdemo.controller.interceptRetry.BuinessException; +import cn.whaifree.springdemo.controller.interceptRetry.ErrorType; +import com.github.benmanes.caffeine.cache.Cache; + +import com.github.benmanes.caffeine.cache.Caffeine; +import com.google.common.collect.Maps; +import com.mysql.cj.util.LogUtils; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import lombok.Getter; +import org.apache.catalina.util.RequestUtil; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.ServletRequestUtils; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.util.WebUtils; + +import java.lang.reflect.Method; +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/9 21:57 + * @注释 + */ +@Aspect +@Component +@Order(100) +public class RetryAspect { + + /** + * 一个Cache只能有一个有效期, + * 所以要根据有效期进行分组 + *

+ * 【exprieTime,【keyOfIp,time】】 + *

+ *

+ * 对不同时间用不同cache实现 + */ + Map> cacheMap = new HashMap<>(); + + @Resource + @Lazy + private ApplicationContext applicationContext; + + @PostConstruct + public void init() { + String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); + for (String beanDefinitionName : beanDefinitionNames) { + // 这里有疑问,可能拿到RetryAspect走getBean导致循环依赖,RetryAspect循环依赖RetryAspect + if (beanDefinitionName.equalsIgnoreCase(this.getClass().getSimpleName())) { + continue; + } + Object bean = applicationContext.getBean(beanDefinitionName); + + Method[] methods = bean.getClass().getDeclaredMethods(); + for (Method method : methods) { + try { + // 手动用反射获取不到注解 + RetryLimit retryLimit = AnnotationUtils.findAnnotation(method, RetryLimit.class); +// RetryLimit retryLimit = method.getAnnotation(RetryLimit.class); + if (retryLimit == null) { + continue; + } + int expireTime = retryLimit.limitTime(); + Cache build = Caffeine.newBuilder().expireAfterAccess(Duration.ofMinutes(expireTime)).maximumSize(1000).build(); + cacheMap.put(expireTime, build); + } catch (Exception e) { + e.printStackTrace(); + } + + } + } + System.out.println(cacheMap); + } + + + + @Around("@annotation(cn.whaifree.springdemo.controller.interceptRetry.aspect.RetryLimit)") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + // 获取方法签名,设置方法可以访问 + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + method.setAccessible(true); + + // 获取注解 + RetryLimit retryAn = AnnotationUtils.findAnnotation(method, RetryLimit.class); + if (retryAn == null) { + return joinPoint.proceed(); + } + + // 如果包含注解,放入缓存,key为ip或者其他限流key,value为次数 + Cache cache = cacheMap.get(retryAn.limitTime()); + String limitKey = retryAn.limitKey(); + if (limitKey == null || limitKey.equals("ip")) { + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = requestAttributes.getRequest(); + limitKey = request.getRemoteAddr(); + }else if (limitKey.equals("userId")) { + // 其他策略 + } + // 如果缓存中没有这个ip访问过,初始化为0 + AtomicInteger atomicInteger = cache.get(limitKey, s -> new AtomicInteger(0)); + if (atomicInteger.intValue() >= retryAn.limitCount()) { + throw new RuntimeException(retryAn.resMsg()); + } + + try { + return joinPoint.proceed(); + } catch (BuinessException e) { + // 如果不是验证错误,向上抛出 + if (!e.getType().equals(ErrorType.RetryType)) { + throw e; + } + // 如果验证错误,对atomic++ + atomicInteger.incrementAndGet(); + String msg = retryAn.resMsg() + ",重试次数:" + atomicInteger.intValue(); + throw new RuntimeException(msg); + } + } + + +} diff --git a/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryLimit.java b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryLimit.java new file mode 100644 index 0000000..69ab419 --- /dev/null +++ b/SpringDemo/src/main/java/cn/whaifree/springdemo/controller/interceptRetry/aspect/RetryLimit.java @@ -0,0 +1,26 @@ +package cn.whaifree.springdemo.controller.interceptRetry.aspect; + +import cn.whaifree.springdemo.controller.interceptRetry.ErrorType; +import cn.whaifree.springdemo.utils.ResVo; +import org.springframework.data.redis.connection.ReturnType; + +import java.lang.annotation.*; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/11/9 21:57 + * @注释 + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RetryLimit { + + int limitCount() default 3; + int limitTime() default 60; + String limitKey() default "ip"; + String resMsg() default "请求过于频繁"; + ErrorType errorType() default ErrorType.RetryType; + +} diff --git a/SpringDemo/src/main/resources/application.yaml b/SpringDemo/src/main/resources/application.yaml index 82e4781..96996c2 100644 --- a/SpringDemo/src/main/resources/application.yaml +++ b/SpringDemo/src/main/resources/application.yaml @@ -8,7 +8,7 @@ my: spring: datasource: - url: jdbc:mysql://localhost:3306/springTest?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai + url: jdbc:mysql://localhost:3306/springTest?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver diff --git a/pom.xml b/pom.xml index 575f05c..7d5d5f9 100644 --- a/pom.xml +++ b/pom.xml @@ -4,10 +4,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + com.whai LeetCode 1.0-SNAPSHOT - jar + pom ForJdk8 ForJdk17 diff --git a/sdoih.bpmn b/sdoih.bpmn new file mode 100644 index 0000000..440f9af --- /dev/null +++ b/sdoih.bpmn @@ -0,0 +1,2 @@ + +