当前位置: 首页 > news >正文

spring boot运行过程中动态加载Controller

1.被加载的jar代码

package com.dl;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}
}
package com.dl;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class JarController {@RequestMapping("/jar")String jar() {return "i  am  a  jar";}}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.dl</groupId><artifactId>jar</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>Spring Boot Blank Project (from https://github.com/making/spring-boot-blank)</name><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><start-class>com.dl.App</start-class><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target><excludes><!-- 去除指定的类--><exclude>**/App.java</exclude></excludes></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.6</version><configuration><archive><addMavenDescriptor>false</addMavenDescriptor></archive></configuration></plugin></plugins></build></project>

工程结构
在这里插入图片描述

2.实现代码

package com.dl;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}
}
package com.dl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** 测试*/
@RestController
public class HelloController {private final TestDynamicLoad testDynamicLoad;@Autowiredpublic HelloController(TestDynamicLoad testDynamicLoad) {this.testDynamicLoad = testDynamicLoad;}@RequestMapping("/")String hello() {return "Hello";}/**** @param path  jar文件的路径* @param fileName  jar文件的名称* @return  加载结果*/@RequestMapping("/load")String load(@RequestParam String path, @RequestParam String fileName) {try {testDynamicLoad.loadJar(path,fileName);} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {e.printStackTrace();return "失败:"+e.getMessage();}return "加载成功";}/**** @param name 卸载jar的名称* @return*/@RequestMapping("/unload")String unload(@RequestParam String name) {try {testDynamicLoad.unloadJar(name);} catch (IllegalAccessException | NoSuchFieldException e) {e.printStackTrace();return "失败:"+e.getMessage();}return "卸载成功";}}
package com.dl;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** 自定义类加载器*/
public class TestClassLoader  extends URLClassLoader{private Map<String, Class<?>> loadedClasses = new ConcurrentHashMap<>();public Map<String, Class<?>> getLoadedClasses() {return loadedClasses;}public TestClassLoader(URL[] urls, ClassLoader parent) {super(urls, parent);}//加载@Overrideprotected Class<?> findClass(String name) {// 从已加载的类集合中获取指定名称的类Class<?> clazz = loadedClasses.get(name);if (clazz != null) {return clazz;}try {// 调用父类的findClass方法加载指定名称的类clazz = super.findClass(name);// 将加载的类添加到已加载的类集合中loadedClasses.put(name, clazz);return clazz;} catch (ClassNotFoundException e) {e.printStackTrace();return null;}}//卸载public void unload() {try {for (Map.Entry<String, Class<?>> entry : loadedClasses.entrySet()) {// 从已加载的类集合中移除该类String className = entry.getKey();loadedClasses.remove(className);try{// 调用该类的destory方法,回收资源Class<?> clazz = entry.getValue();Method destory = clazz.getDeclaredMethod("destory");destory.invoke(clazz);} catch (Exception e ) {// 表明该类没有destory方法}}// 从其父类加载器的加载器层次结构中移除该类加载器close();} catch (Exception e) {e.printStackTrace();}}}
package com.dl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;@Component
public class TestDynamicLoad {@Autowiredprivate ApplicationContext applicationContext;private Map<String, TestClassLoader> myClassLoaderCenter = new ConcurrentHashMap<>();/*** 动态加载指定路径下指定jar包* @param path* @param fileName*/public void loadJar(String path, String fileName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {//获取jar文件File file = new File(path +"/" + fileName);// 获取beanFactoryDefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();try {//创建URLConnectionURL url = new URL("jar:file:" + file.getAbsolutePath() + "!/");URLConnection urlConnection = url.openConnection();JarURLConnection jarURLConnection = (JarURLConnection)urlConnection;// 获取jar文件JarFile jarFile = jarURLConnection.getJarFile();Enumeration<JarEntry> entries = jarFile.entries();// 创建自定义类加载器,并加到map中方便管理TestClassLoader myClassloader = new TestClassLoader(new URL[] { url }, ClassLoader.getSystemClassLoader());myClassLoaderCenter.put(fileName, myClassloader);// 遍历文件while (entries.hasMoreElements()) {JarEntry jarEntry = entries.nextElement();if (jarEntry.getName().endsWith(".class")) {// 1. 加载类到jvm中// 获取类的全路径名String className = jarEntry.getName().replace('/', '.').substring(0, jarEntry.getName().length() - 6);// 1.1进行反射获取myClassloader.loadClass(className);}}Map<String, Class<?>> loadedClasses = myClassloader.getLoadedClasses();for(Map.Entry<String, Class<?>> entry : loadedClasses.entrySet()){String className = entry.getKey();Class<?> clazz = entry.getValue();// 此处beanName使用全路径名是为了防止beanName重复String packageName = className.substring(0, className.lastIndexOf(".") + 1);String beanName = className.substring(className.lastIndexOf(".") + 1);beanName = packageName + beanName.substring(0, 1).toLowerCase() + beanName.substring(1);// 2. 将有@spring注解的类交给spring管理// 2.1 判断类的类型String flag = hasSpringAnnotation(clazz);if(!flag.equals("pass")){// 2.2交给spring管理BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();// 2.3注册到spring的beanFactory中beanFactory.registerBeanDefinition(beanName, beanDefinition);// 2.4允许注入和反向注入beanFactory.autowireBean(clazz);beanFactory.initializeBean(clazz, beanName);// 2.5手动构建实例,并注入base service 防止卸载之后不再生成Object obj = clazz.newInstance();beanFactory.registerSingleton(beanName, obj);//3.特殊处理//3.1不同的spring核心类不同的处理,实例中只是写了contrllerhandle(flag,beanName);}}} catch (IOException e) {e.printStackTrace();throw new RuntimeException("读取jar文件异常: " + fileName);}}/*** 判断一个类是具体类型,如果是spring核心类需要交给spring管理* @param clazz 要检查的类* @return string 如果该类上添加了相应的 Spring 注解返回对应标识;否则返回 pass*/private  String hasSpringAnnotation(Class<?> clazz) {if (clazz == null) {return "pass";}//是否是接口if (clazz.isInterface()) {return "pass";}//是否是抽象类if (Modifier.isAbstract(clazz.getModifiers())) {return "pass";}//常规注解效验和处理try {if (clazz.getAnnotation(Component.class) != null ) {return "Component";}if (clazz.getAnnotation(Repository.class) != null) {return "Repository";}if (clazz.getAnnotation(Service.class) != null ) {return "Service";}if (clazz.getAnnotation(Configuration.class) != null ) {return "Configuration";}if (clazz.getAnnotation(Controller.class) != null || clazz.getAnnotation(RestController.class) != null) {return "Controller";}}catch (Exception e){e.printStackTrace();}return "pass";}/*** 处理类* @param type 类型标识* @param name bean名称*/private  void handle(String type ,String name){//这里只做了contrller类型标识的处理if(type.equals("Controller")){RequestMappingHandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);// 注册ControllerMethod method = null;try {method = handlerMapping.getClass().getSuperclass().getSuperclass().getDeclaredMethod("detectHandlerMethods", Object.class);} catch (NoSuchMethodException e) {e.printStackTrace();}// 将private改为可使用assert method != null;method.setAccessible(true);try {method.invoke(handlerMapping, name);} catch (IllegalAccessException | InvocationTargetException e) {e.printStackTrace();}}}/*** 动态卸载* @param name  卸载jar的名称*/public void unloadJar(String name) throws IllegalAccessException, NoSuchFieldException {// 获取加载当前jar的类加载器TestClassLoader myClassLoader = myClassLoaderCenter.get(name);// 获取beanFactory,准备从spring中卸载DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();Map<String, Class<?>> loadedClasses = myClassLoader.getLoadedClasses();Set<String> beanNames = new HashSet<>();for (Map.Entry<String, Class<?>> entry: loadedClasses.entrySet()) {// 截取beanNameString key = entry.getKey();String packageName = key.substring(0, key.lastIndexOf(".") + 1);String beanName = key.substring(key.lastIndexOf(".") + 1);beanName = packageName + beanName.substring(0, 1).toLowerCase() + beanName.substring(1);// 获取bean,如果获取失败,表名这个类没有加到spring容器中,则跳出本次循环Object bean = null;try{bean = applicationContext.getBean(beanName);}catch (Exception e){// 异常说明spring中没有这个beancontinue;}// 从spring中移除,这里的移除是仅仅移除的bean,并未移除bean定义beanNames.add(beanName);beanFactory.destroyBean(beanName, bean);}// 移除bean定义Field mergedBeanDefinitions = beanFactory.getClass().getSuperclass().getSuperclass().getDeclaredField("mergedBeanDefinitions");mergedBeanDefinitions.setAccessible(true);Map<String, RootBeanDefinition> rootBeanDefinitionMap = ((Map<String, RootBeanDefinition>) mergedBeanDefinitions.get(beanFactory));for (String beanName : beanNames) {beanFactory.removeBeanDefinition(beanName);// 父类bean定义去除rootBeanDefinitionMap.remove(beanName);}// 从类加载中移除try {// 从类加载器底层的classes中移除连接Field field = ClassLoader.class.getDeclaredField("classes");field.setAccessible(true);Vector<Class<?>> classes = (Vector<Class<?>>) field.get(myClassLoader);classes.removeAllElements();// 移除类加载器的引用myClassLoaderCenter.remove(name);// 卸载类加载器myClassLoader.unload();} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}}}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.dl</groupId><artifactId>li</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>Spring Boot Blank Project (from https://github.com/making/spring-boot-blank)</name><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><start-class>com.dl.App</start-class><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.6.0</version></plugin></plugins></build></project>

3.测试

①启动项目
在这里插入图片描述

②测试url
在这里插入图片描述

③没有加载jar前
在这里插入图片描述

④加载jar
在这里插入图片描述

⑤加载后验证
在这里插入图片描述

⑥卸载jar
在这里插入图片描述

⑦验证
在这里插入图片描述

相关文章:

spring boot运行过程中动态加载Controller

1.被加载的jar代码 package com.dl;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication public class App {public static void main(String[] args) {SpringApplication.run(A…...

学习软考----数据库系统工程师25

关系规范化 1NF&#xff08;第一范式&#xff09; 2NF&#xff08;第二范式&#xff09; 3NF&#xff08;第三范式&#xff09; BCNF&#xff08;巴克斯范式&#xff09; 4NF&#xff08;第四范式&#xff09; 总结...

RTMP 直播推流 Demo(一)—— 项目配置与视频预览

音视频编解码系列目录&#xff1a; Android 音视频基础知识 Android 音视频播放器 Demo&#xff08;一&#xff09;—— 视频解码与渲染 Android 音视频播放器 Demo&#xff08;二&#xff09;—— 音频解码与音视频同步 RTMP 直播推流 Demo&#xff08;一&#xff09;—— 项目…...

安卓获取SHA

1&#xff1a;安卓通过签名key获取SHA 方式有两种&#xff0c; 1、电脑上来存在eclipse的用户或正在使用此开发工具的用户就简单了&#xff0c;直接利用eclipse 走打包流程&#xff0c;再打包的时候选择相应的签名&#xff0c;那么在当前面板的下面便会出现签名的相关信息。 2、…...

【Qt 学习笔记】Qt常用控件 | 输入类控件 | Dial的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 输入类控件 | Dial的使用及说明 文章编号&#xff1a;Qt…...

【C语言】项目实践-贪吃蛇小游戏(Windows环境的控制台下)

一.游戏要实现基本的功能&#xff1a; • 贪吃蛇地图绘制 • 蛇吃食物的功能 &#xff08;上、下、左、右方向键控制蛇的动作&#xff09; • 蛇撞墙死亡 • 蛇撞自身死亡 • 计算得分 • 蛇身加速、减速 • 暂停游戏 二.技术要点 C语言函数、枚举、结构体、动态内存管…...

在做题中学习(50):搜索插入位置

35. 搜索插入位置 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a;二分查找 思路&#xff1a;题目是有序的&#xff0c;时间复杂度O(logN),二分没跑了&#xff0c;题目说如果找不到target&#xff0c;返回它应该被插入位置的下标&#xff0c;所以可以分析一下示例2&…...

【mysql】mysql单表查询、多表查询、分组查询、子查询等案例详细解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

【Gateway远程开发】0.5GB of free space is necessary to run the IDE.

【Gateway远程开发】0.5GB of free space is necessary to run the IDE. 报错 0.5GB of free space is necessary to run the IDE. Make sure that there’s enough space in following paths: /root/.cache/JetBrains /root/.config/JetBrains 原因 下面两个路径的空间不…...

普通组件的注册-局部注册和全局注册

目录 一、局部注册和全局注册-概述 二、局部注册的使用示例 三、全局注册的使用示例 一、局部注册和全局注册-概述 组件注册有两种方式&#xff1a; 局部注册&#xff1a;只能在注册的组件内使用。使用方法&#xff1a;创建.vue文件&#xff0c;在使用的组件内导入并注册。…...

Apache Dubbo知识点表格总结

Dubbo是一个高性能的Java RPC框架&#xff0c;它提供了一系列的功能来支持分布式系统的开发。通常用于微服务之间的服务调用&#xff0c;顺便提一下也是用于微服务之间调用的OpenFeign&#xff0c;OpenFeign是Spring Cloud体系中的一个声明式HTTP客户端&#xff0c;用于简化HTT…...

电路板/硬件---器件

电阻 电阻作用 电阻在电路中扮演着重要的角色&#xff0c;其作用包括&#xff1a; 限制电流&#xff1a;电阻通过阻碍电子流动的自由而限制电流。这是电阻最基本的功能之一。根据欧姆定律&#xff0c;电流与电阻成正比&#xff0c;电阻越大&#xff0c;通过电阻的电流就越小。…...

STC15W1K16S和VC6.0串口通讯收发测试实例

/********************************************* STC USB 串口板 2014 4 7 20:12 发送接收数据 使用STC串口调试助手通讯正常&#xff0c;L161 **********************************************/ #include "reg51.h" #include "intrins.h" #define…...

Python程序设计 函数(三)

练习十一 函数 第1关&#xff1a; 一元二次方程的根 定义一个函数qg&#xff0c;输入一元二次方程的系数a,b,c 当判别式大于0&#xff0c;返回1和两个根 当判别式等于0&#xff0c;返回0和两个根 当判别式小于0&#xff0c;访问-1和两个根 在主程序中&#xff0c;根据函数返回…...

linux之ssh

SSH远程连接协议 SSH远程管理 定义 SSH&#xff08;Secure Shell &#xff09;是一种安全通道协议&#xff0c;主要用来实现字符界面的远程的登录、远程复制等功能。 SSH协议对通信双方的数据传输进行了加密处理&#xff0c;其中包括用户登录时输入的用户口令。因此SSH协议具…...

excel如何将多列数据转换为一列?

这个数据整理借用数据透视表也可以做到&#xff1a; 1.先将数据源的表头补齐&#xff0c;“姓名” 2.点击插入选项卡&#xff0c;数据透视表&#xff0c;在弹出对话框中&#xff0c;数据透视位置选择 现有工作表&#xff0c;&#xff08;实际使用时新建也没有问题&#xff09;…...

【Java 刷题记录】前缀和

前缀和 25. 一维前缀和 示例1&#xff1a; 输入&#xff1a; 3 2 1 2 4 1 2 2 3输出&#xff1a; 3 6import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(S…...

NVIDIA: RULER新测量方法让大模型现形

1 引言 最近在人工智能系统工程和语言模型设计方面的进展已经实现了语言模型上下文长度的高效扩展。以前的工作通常采用合成任务,如密钥检索和大海捞针来评估长上下文语言模型(LMs)。然而,这些评估在不同工作中使用不一致,仅揭示了检索能力,无法衡量其他形式的长上下文理解。 …...

2024数学-微积分和线性代数/本科研究生专业考试/考研/论文/重点公式考点汇总/最难公式投票

## 整体公式汇总列表 http://www.deepnlp.org/equation/category/math #### 微积分 ## 几何级数http://www.deepnlp.org/equation/arithmetic-and-geometric-progressions ## 级数收敛http://www.deepnlp.org/equation/convergence-of-series ## 二项式展开 http://www.dee…...

代码随想录训练营Day33(贪心算法):Leetcode1005、134、135(难得有一天能完全独立做出题目)

Leetcode1005: 题目描述&#xff1a; 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以这种方式修改数组后&#xff0c;返回数…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...