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

SpringBoot Starter自定义:创建可复用的自动配置模块

在这里插入图片描述

文章目录

    • 引言
    • 一、自定义Starter基础知识
    • 二、创建自动配置模块
      • 2.1 项目结构搭建
      • 2.2 配置属性类
      • 2.3 服务接口及实现
      • 2.4 自动配置类
      • 2.5 spring.factories文件
      • 2.6 Maven依赖配置
    • 三、创建Starter模块
      • 3.1 项目结构
      • 3.2 Maven依赖配置
    • 四、使用自定义Starter
      • 4.1 添加依赖
      • 4.2 配置属性
      • 4.3 使用示例
    • 五、Starter高级特性
      • 5.1 条件化配置
      • 5.2 自动配置顺序控制
      • 5.3 配置元数据
    • 总结

引言

Spring Boot Starter是Spring Boot生态系统的核心组成部分,它极大地简化了项目的依赖管理和配置过程。通过Starter机制,开发者只需引入相应的依赖,Spring Boot就能自动完成复杂的配置工作。对于企业级应用开发,我们经常需要在多个项目中复用某些通用功能,这时创建自定义Starter就显得尤为重要。本文将详细介绍如何设计和实现一个自定义的Spring Boot Starter,帮助读者掌握这一强大技术,提升代码复用性和开发效率。

一、自定义Starter基础知识

Spring Boot Starter本质上是一组依赖项的集合,同时结合自动配置类,为特定功能提供开箱即用的体验。自定义Starter的核心目标是将可复用的功能模块化,让其他项目能够通过简单的依赖引入来使用这些功能。

一个标准的Spring Boot Starter通常由两个主要组件构成:自动配置模块和Starter模块。自动配置模块包含功能的具体实现和配置类,而Starter模块则作为一个空壳,仅依赖于自动配置模块和其他必要的依赖。这种分离设计使得功能实现与依赖管理解耦,提高了模块的灵活性。

以下是自定义Starter的基本命名规范:

// 对于官方Starter,命名格式为:
spring-boot-starter-{功能名}// 对于非官方Starter,命名格式为:
{项目名}-spring-boot-starter

命名规范的遵循有助于区分官方与第三方Starter,避免潜在的命名冲突。

二、创建自动配置模块

自动配置模块是Starter的核心,它包含了功能的具体实现和自动配置类。我们以创建一个简单的数据加密Starter为例,展示自动配置模块的创建过程。

2.1 项目结构搭建

首先创建一个Maven项目,命名为encryption-spring-boot-autoconfigure,作为自动配置模块。项目结构如下:

encryption-spring-boot-autoconfigure/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── encryption/
│   │   │               ├── autoconfigure/
│   │   │               │   └── EncryptionAutoConfiguration.java
│   │   │               ├── properties/
│   │   │               │   └── EncryptionProperties.java
│   │   │               └── service/
│   │   │                   ├── EncryptionService.java
│   │   │                   └── impl/
│   │   │                       └── AESEncryptionServiceImpl.java
│   │   └── resources/
│   │       └── META-INF/
│   │           └── spring.factories
└── pom.xml

2.2 配置属性类

创建配置属性类,用于存储和管理加密服务的相关配置:

package com.example.encryption.properties;import org.springframework.boot.context.properties.ConfigurationProperties;/*** 加密服务配置属性类* 通过@ConfigurationProperties注解绑定配置文件中的属性*/
@ConfigurationProperties(prefix = "encryption")
public class EncryptionProperties {/*** 加密算法,默认为AES*/private String algorithm = "AES";/*** 加密密钥*/private String key = "defaultKey123456";/*** 是否启用加密服务*/private boolean enabled = true;// Getter和Setter方法public String getAlgorithm() {return algorithm;}public void setAlgorithm(String algorithm) {this.algorithm = algorithm;}public String getKey() {return key;}public void setKey(String key) {this.key = key;}public boolean isEnabled() {return enabled;}public void setEnabled(boolean enabled) {this.enabled = enabled;}
}

2.3 服务接口及实现

定义加密服务接口及其实现:

package com.example.encryption.service;/*** 加密服务接口* 定义加密和解密的基本操作*/
public interface EncryptionService {/*** 加密字符串* * @param content 待加密内容* @return 加密后的内容*/String encrypt(String content);/*** 解密字符串* * @param encryptedContent 已加密内容* @return 解密后的原文*/String decrypt(String encryptedContent);
}

AES加密实现类:

package com.example.encryption.service.impl;import com.example.encryption.properties.EncryptionProperties;
import com.example.encryption.service.EncryptionService;import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;/*** AES加密服务实现* 提供基于AES算法的加密和解密功能*/
public class AESEncryptionServiceImpl implements EncryptionService {private final EncryptionProperties properties;public AESEncryptionServiceImpl(EncryptionProperties properties) {this.properties = properties;}@Overridepublic String encrypt(String content) {try {// 创建密钥规范SecretKeySpec keySpec = new SecretKeySpec(properties.getKey().getBytes(StandardCharsets.UTF_8),properties.getAlgorithm());// 获取Cipher实例Cipher cipher = Cipher.getInstance(properties.getAlgorithm());// 初始化为加密模式cipher.init(Cipher.ENCRYPT_MODE, keySpec);// 执行加密byte[] encrypted = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));// 返回Base64编码后的加密结果return Base64.getEncoder().encodeToString(encrypted);} catch (Exception e) {throw new RuntimeException("加密失败", e);}}@Overridepublic String decrypt(String encryptedContent) {try {// 创建密钥规范SecretKeySpec keySpec = new SecretKeySpec(properties.getKey().getBytes(StandardCharsets.UTF_8),properties.getAlgorithm());// 获取Cipher实例Cipher cipher = Cipher.getInstance(properties.getAlgorithm());// 初始化为解密模式cipher.init(Cipher.DECRYPT_MODE, keySpec);// 执行解密byte[] original = cipher.doFinal(Base64.getDecoder().decode(encryptedContent));// 返回解密后的原文return new String(original, StandardCharsets.UTF_8);} catch (Exception e) {throw new RuntimeException("解密失败", e);}}
}

2.4 自动配置类

创建自动配置类,根据条件自动装配加密服务:

package com.example.encryption.autoconfigure;import com.example.encryption.properties.EncryptionProperties;
import com.example.encryption.service.EncryptionService;
import com.example.encryption.service.impl.AESEncryptionServiceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 加密服务自动配置类* 负责根据条件自动装配加密服务*/
@Configuration
@ConditionalOnClass(EncryptionService.class)
@EnableConfigurationProperties(EncryptionProperties.class)
@ConditionalOnProperty(prefix = "encryption", name = "enabled", havingValue = "true", matchIfMissing = true)
public class EncryptionAutoConfiguration {/*** 注册加密服务Bean* 当容器中不存在EncryptionService类型的Bean时,创建默认实现*/@Bean@ConditionalOnMissingBeanpublic EncryptionService encryptionService(EncryptionProperties properties) {return new AESEncryptionServiceImpl(properties);}
}

2.5 spring.factories文件

META-INF目录下创建spring.factories文件,指定自动配置类:

# 自动配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.encryption.autoconfigure.EncryptionAutoConfiguration

2.6 Maven依赖配置

pom.xml文件配置:

<?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.example</groupId><artifactId>encryption-spring-boot-autoconfigure</artifactId><version>1.0.0</version><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><spring-boot.version>2.7.0</spring-boot.version></properties><dependencies><!-- Spring Boot AutoConfigure --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId><version>${spring-boot.version}</version></dependency><!-- 用于生成配置元数据 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><version>${spring-boot.version}</version><optional>true</optional></dependency></dependencies>
</project>

三、创建Starter模块

Starter模块是一个空壳模块,它依赖于自动配置模块和其他必要的依赖,向使用者提供一站式的依赖引入体验。

3.1 项目结构

创建一个Maven项目,命名为encryption-spring-boot-starter,作为Starter模块:

encryption-spring-boot-starter/
└── pom.xml

3.2 Maven依赖配置

pom.xml文件配置:

<?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.example</groupId><artifactId>encryption-spring-boot-starter</artifactId><version>1.0.0</version><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target></properties><dependencies><!-- 依赖自动配置模块 --><dependency><groupId>com.example</groupId><artifactId>encryption-spring-boot-autoconfigure</artifactId><version>1.0.0</version></dependency><!-- 依赖其他必要的库,根据功能需求添加 --></dependencies>
</project>

四、使用自定义Starter

创建完成后,我们可以在其他项目中使用这个自定义的Starter。

4.1 添加依赖

在项目的pom.xml中添加依赖:

<dependency><groupId>com.example</groupId><artifactId>encryption-spring-boot-starter</artifactId><version>1.0.0</version>
</dependency>

4.2 配置属性

application.propertiesapplication.yml中配置加密服务属性:

# 开启加密服务
encryption.enabled=true
# 设置加密算法
encryption.algorithm=AES
# 设置加密密钥
encryption.key=mySecretKey12345

4.3 使用示例

在业务代码中注入并使用加密服务:

package com.example.demo;import com.example.encryption.service.EncryptionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** 加密服务演示控制器* 展示如何在业务代码中使用自定义Starter提供的功能*/
@RestController
public class EncryptionController {private final EncryptionService encryptionService;@Autowiredpublic EncryptionController(EncryptionService encryptionService) {this.encryptionService = encryptionService;}@GetMapping("/encrypt")public String encrypt(@RequestParam String content) {return encryptionService.encrypt(content);}@GetMapping("/decrypt")public String decrypt(@RequestParam String content) {return encryptionService.decrypt(content);}
}

五、Starter高级特性

5.1 条件化配置

Spring Boot提供了丰富的条件注解,用于控制Bean的装配条件,使自定义Starter更加灵活:

// 当类路径下存在指定类时生效
@ConditionalOnClass(name = "com.example.SomeClass")// 当Bean不存在时生效
@ConditionalOnMissingBean// 当配置属性满足条件时生效
@ConditionalOnProperty(prefix = "feature", name = "enabled", havingValue = "true")// 当环境为指定profile时生效
@ConditionalOnProfile("dev")// 当Web应用为Servlet类型时生效
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)

5.2 自动配置顺序控制

在复杂场景下,可能需要控制多个自动配置类的执行顺序,可以使用@AutoConfigureBefore@AutoConfigureAfter注解:

// 在指定自动配置类之前执行
@AutoConfigureBefore(OtherAutoConfiguration.class)// 在指定自动配置类之后执行
@AutoConfigureAfter(OtherAutoConfiguration.class)// 示例代码
@Configuration
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class EncryptionAutoConfiguration {// 配置代码
}

5.3 配置元数据

为了提供更好的IDE支持,可以创建配置元数据文件:

{"groups": [{"name": "encryption","type": "com.example.encryption.properties.EncryptionProperties","sourceType": "com.example.encryption.properties.EncryptionProperties"}],"properties": [{"name": "encryption.enabled","type": "java.lang.Boolean","description": "是否启用加密服务","sourceType": "com.example.encryption.properties.EncryptionProperties","defaultValue": true},{"name": "encryption.algorithm","type": "java.lang.String","description": "加密算法","sourceType": "com.example.encryption.properties.EncryptionProperties","defaultValue": "AES"},{"name": "encryption.key","type": "java.lang.String","description": "加密密钥","sourceType": "com.example.encryption.properties.EncryptionProperties","defaultValue": "defaultKey123456"}],"hints": [{"name": "encryption.algorithm","values": [{"value": "AES","description": "AES加密算法"},{"value": "DES","description": "DES加密算法"}]}]
}

配置元数据文件应放在META-INF/spring-configuration-metadata.json路径下,通常由spring-boot-configuration-processor自动生成。

总结

Spring Boot Starter是一种强大的自动配置机制,通过自定义Starter,我们可以将业务中的通用功能模块化,实现代码的高度复用。自定义Starter的核心在于合理设计自动配置类和配置属性类,让用户能够通过简单的配置来定制功能行为。在创建过程中,我们需要遵循Spring Boot的命名规范和最佳实践,将自动配置模块与Starter模块分离,提高灵活性。通过条件化配置和自动配置顺序控制,可以让Starter在复杂场景中也能稳定工作。对于企业级应用开发,自定义Starter是提升团队效率的关键工具,它不仅能简化项目配置,还能确保各个项目遵循统一的最佳实践,降低维护成本。

相关文章:

SpringBoot Starter自定义:创建可复用的自动配置模块

文章目录 引言一、自定义Starter基础知识二、创建自动配置模块2.1 项目结构搭建2.2 配置属性类2.3 服务接口及实现2.4 自动配置类2.5 spring.factories文件2.6 Maven依赖配置 三、创建Starter模块3.1 项目结构3.2 Maven依赖配置 四、使用自定义Starter4.1 添加依赖4.2 配置属性…...

服务器风扇故障导致过热问题的解决方案

# 服务器风扇故障导致过热问题的解决方案 ## 一、故障诊断与确认 ### 1. 确认风扇故障现象 bash # 检查系统日志中的硬件错误 dmesg | grep -i fan journalctl -b | grep -i thermal # 查看传感器数据&#xff08;需要安装lm-sensors&#xff09; sudo sensors-detect sudo …...

[OS] vDSO + vvar(频繁调用的处理) | 存储:寄存器(高效)和栈(空间大)| ELF标准包装规范(加速程序加载)

vDSO vvar 一、社区公告板系统&#xff08;类比 vDSO vvar&#xff09; 想象你住在一个大型社区&#xff0c;管理员&#xff08;内核&#xff09;需要向居民&#xff08;用户程序&#xff09;提供实时信息&#xff08;如天气预报、社区活动时间等&#xff09;。直接让每个居…...

SQL刷题日志(day1)

1、substring_index&#xff08;截取字符串&#xff09; 参数说明&#xff1a; profile&#xff1a;要处理的字符串字段。,&#xff1a;分隔符。-1&#xff1a;表示从字符串的右侧开始截取&#xff0c;第一个出现的分隔符后面的所有内容。 SELECT SUBSTRING_INDEX(profile, ,…...

爬虫:一文掌握 curl-cffi 的详细使用(支持 TLS/JA3 指纹仿真的 cURL 库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、curl-cffi 概述1.1 curl-cffi介绍1.2 主要特性1.3 适用场景1.4 使用 curl-cffi 的注意事项1.5 与 requests 和 pycurl 对比1.6 curl-cffi 的安装二、基本使用2.1 同步请求2.2 异步请求三、高级功能3.1 模拟浏览器指…...

前端开发基础:HTML 与 CSS 入门详解

目录 一、HTML 基础 &#xff08;一&#xff09;HTML 概述 &#xff08;二&#xff09;HTML 标签 标签分类 常用标签详解 &#xff08;三&#xff09;HTML 注释 二、CSS 样式 &#xff08;一&#xff09;CSS 概述 &#xff08;二&#xff09;CSS 引入方式 &#xff0…...

实时语音交互数字人VideoChat,可自定义形象与音色,支持音色克隆,首包延迟低至3s

简介 实时语音交互数字人&#xff0c;支持端到端语音方案&#xff08;GLM-4-Voice - THG&#xff09;和级联方案&#xff08;ASR-LLM-TTS-THG&#xff09;。用户可通过麦克风或文本输入&#xff0c;与数字人进行语音或视频交互。 目前支持的功能 支持自定义形象TTS模块添加音…...

25.OpenCV中的霍夫圆变换

OpenCV中的霍夫圆变换 在图像处理与计算机视觉中&#xff0c;圆形检测是一项常见的任务&#xff0c;应用场景包括车牌识别、瞳孔检测、交通标志识别等。霍夫圆变换&#xff08;Hough Circle Transform&#xff09;是一种高效且鲁棒的算法&#xff0c;通过在参数空间中寻找局部…...

OpenTiny使用指南

最近项目里用到了一个新的组件库——OpenTiny&#xff0c;但是官方文档的使用指南的描述很复杂&#xff0c;花了一些时间尝试才正常使用。下面是一个使用步骤的描述&#xff0c;可放心食用&#xff1a; 一、安装 TinyVue 组件库同时支持 Vue 2.0 和 Vue 3.0 框架&#xff0c;…...

Uniapp: 大纲

目录 一、基础巩固1.1、Uniapp:下拉选择框ba-tree-picker 二、项目配置2.1、Uniapp&#xff1a;修改端口号2.2、Uniapp&#xff1a;本地存储 一、基础巩固 1.1、Uniapp:下拉选择框ba-tree-picker 二、项目配置 2.1、Uniapp&#xff1a;修改端口号 2.2、Uniapp&#xff1a;本…...

A2A协议实现详解及示例

A2A协议概述 A2A (Agent2Agent) 是Google推出的一个开放协议&#xff0c;旨在使AI智能体能够安全地相互通信和协作。该协议打破了孤立智能体系统之间的壁垒&#xff0c;实现了复杂的跨应用自动化。[1] A2A协议的核心目标是让不同的AI代理能够相互通信、安全地交换信息以及在各…...

HTTP协议入门

文章目录 1. 概述2. 请求协议2.1 Get 方式请求协议2.2 POST 方式的请求2.3 获取请求数据 3. 响应协议3.1 响应数据格式3.2 设置响应数据 1. 概述 概念 &#xff1a;Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则…...

远程控制Android手机(web-scrcpy)

最近有web远程查看和控制Android手机的需求&#xff0c;研究了一下scrcpy&#xff0c;发现还是比较容易实现远程控制&#xff0c;所以自己就用flask写了一个web远程控制的scrcpy&#xff0c;算是推荐一下自己的作品&#xff0c;作品地址&#xff1a;https://github.com/baixin1…...

在AWS EC2上部署网站的完整步骤指南

本文详细介绍如何从零开始在AWS EC2实例上部署静态/动态网站&#xff0c;涵盖实例创建、安全组配置、环境搭建及域名绑定等关键步骤。 一、准备工作 AWS账号&#xff1a;访问 AWS官网 注册账号并完成信用卡绑定 本地工具&#xff1a; SSH客户端&#xff08;Mac/Linux自带终端&…...

CentOS下,Xftp中文文件名乱码的处理方式

乱码原因 中文版Windows默认使用GBK编码&#xff0c;现代Linux发行版&#xff08;如CentOS、Ubuntu等&#xff09;默认使用UTF-8编码。Windows下正常的编码&#xff0c;可能在linux下无法识别&#xff0c;例如&#xff1a;Windows的GBK字节0xD6D0被Linux用UTF-8解码时&#xf…...

Linux vagrant 导入ubuntu到virtualbox

前言 vagrant 导入ubuntu虚拟机 前提要求 安装 virtualbox 和vagrant<vagrant-disksize> (Linux 方式 Windows 方式) 创建一键部署ubuntu虚拟机 /opt/vagrant 安装目录/opt/VirtualBox 安装目录/opt/ubuntu22/Vagrantfile &#xff08;可配置网络IP&#xff0c;内存…...

2025高频面试算法总结篇【动态规划】

文章目录 直接刷题链接直达编辑距离最长回文子串完全平方数最长递增子序列正则表达式匹配零钱兑换鸡蛋掉落单词拆分 直接刷题链接直达 动态规划&#xff08;Dynamic Programming, DP&#xff09;是一种通过拆解子问题并利用子问题的最优解来构建整体问题的最优解的方法&#x…...

FPGA_UART

1.UART 概述 &#xff08;通用异步收发传输器&#xff09; 1. 基本定义 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;是一种常见的串行通信协议&#xff0c;用于在设备间通过异步串行通信传输数据。它不依赖独立的时钟信号&#xff0c;而是通过预…...

绿算轻舟系列FPGA加速卡:驱动数字化转型的核心动力

在数字化浪潮席卷全球的今天&#xff0c;算力已成为推动企业创新和行业升级的核心引擎。绿算轻舟系列FPGA加速卡凭借其高性能、低延迟、高能效比的独特优势&#xff0c;正成为各领域智能化转型的“隐形加速器”。它以灵活的硬件架构和强大的并行计算能力&#xff0c;为复杂场景…...

gitee基本使用

git实用手册 git全局设置 git config --global user.name "yourname" git config --global user.email "youremail"推代码时的账号&#xff08;email) 版本回退 git loggit reset –hard <码>git push -f HTTPS步骤(上传) 拉取项目 1、新建一个…...

最短路径介绍

最短路径是图论中的算法&#xff0c;下面将列举几个常见的算法&#xff1a; &#x1f697; 一、单源最短路径&#xff08;一个起点到所有点&#xff09; 1. Dijkstra 算法 适用图&#xff1a;非负权图&#xff08;不能有负权边&#xff09; 思路&#xff1a;贪心 最小堆&am…...

VRRP 基础全解析:从结构到配置

目录 VRRP基本概述 VRRP基本结构 状态机 ​编辑 负载分担 &#xff08;多个VRRP&#xff09; VRRP基本概述 VRRP能够在不改变组网的情况下&#xff0c;将多台路由器虚拟成一个虚拟路由器&#xff0c;通过配置虚拟路由器的IP地址为默认网关&#xff0c;实现网关的备份。协…...

【NIO番外篇】之组件 Buffer

目录 一、Buffer&#xff1a;数据界的“快递小哥”/“临时仓库管理员” &#x1f609;什么是 Buffer&#xff1f;它的作用是什么&#xff1f; 二、Buffer 的“三围”和“书签”&#x1f4cc;&#xff1a;核心属性1. Capacity (容量)&#xff1a;2. Position (位置)&#xff1a;…...

Python基础知识(一、基础语法)

Python基础知识&#xff08;一、基础语法&#xff09; 字面量注释单行注释多行注释 变量数据类型数据类型查看数据类型转换 标识符命名规范不可使用关键字 运算符算数运算符赋值运算符 字符串字符串的定义方式字符串拼接占位拼接数字精度控制快速格式化 数据输入逻辑运算比较运…...

C语言题目自增在前与在后

一、题目引入 谨记真言: i的值最终都会改变 只是表达式的值不同 二、分析题目 if判断语句里面要条件为真执行时 printf语句 i 变量在前 使用i的当前值是1 i的值就是1与1相等 所以&&左边的为真 但是&&存在 必须前后都为真才为真 所以还要看&&后面…...

【口腔粘膜鳞状细胞癌】文献阅读

写在前面 看看文章&#xff0c;看看有没有思路 文献 The regulatory role of cancer stem cell marker gene CXCR4 in the growth and metastasis of gastric cancer IF:6.8 中科院分区:1区 医学WOS分区: Q1 目的&#xff1a;通过 scRNA-seq 结合大量 RNA-seq 揭示癌症干细胞…...

如何撤回刚提交的 commit

如何撤回刚提交的 commit 如果刚刚执行了 git commit 但想撤销这个提交&#xff0c;有几种方法可以实现&#xff0c;具体取决于你想达到的效果&#xff1a; 1. 撤销 commit 但保留更改&#xff08;修改回到暂存区&#xff09; git reset --soft HEAD~1这会撤销最后一次提交提…...

deepin使用autokey添加微信快捷键一键显隐ctrl+alt+w

打开deepin商店&#xff0c;搜索快捷键&#xff0c;找到autokey 快捷键管理&#xff0c;点击安装 点击右键新建文件夹 点击右键新建脚本 打开脚本并添加以下内容 import subprocess import time# ------------------ 配置项 ------------------ WM_CLASS "wechat…...

开源微调混合推理模型:cogito-v1-preview-qwen-32B

一、模型概述 1.1 模型特点 Cogito v1-preview-qwen-32B 是一款基于指令微调的生成式语言模型&#xff08;LLM&#xff09;&#xff0c;具有以下特点&#xff1a; 支持直接回答&#xff08;标准模式&#xff09;和自我反思后再回答&#xff08;推理模式&#xff09;。使用 I…...

【uniapp-兼容性处理】swiper在iOS上偶发出现后几张图片白屏情况

【日期】2025-04-14 【问题】 swiper在iOS上偶发出现后几张图片白屏情况 swiper内部的几个swiper-item垂直排列&#xff0c;各自进行滚动&#xff0c;样式方面兼容性出现问题 【原因】&#xff1a; 原代码&#xff1a;&#xff08;不应在swiper-item添加style属性&#xf…...

go中new和make有什么异同?

相同点&#xff1a;都是给变量分配内存 不同点&#xff1a; 作用类型不同。new通常给int、string、数组类型的变量分配内存&#xff0c;而make通常给slice、map、channel分配内存。返回值类型不同。new返回指向变量的指针&#xff0c;make返回的是变量本身new分配内存空间后&…...

RabbitMQ 深度解析:从基础到高级应用的全面指南

&#x1f430; RabbitMQ 深度解析&#xff1a;从基础到高级应用的全面指南 前言&#x1f4d8; 一、RabbitMQ 简介⚙️ 二、核心特性可靠性 &#x1f512;灵活路由 &#x1f504;高可用性 &#x1f310;多协议支持 &#x1f30d;多语言客户端 &#x1f4bb;插件机制 &#x1f50…...

动手强化学习之马尔可夫决策(机器人篇)

1 马尔可夫决策过程 马尔可夫决策过程&#xff08;Markov Decision Process, MDP&#xff09;是一种数学框架&#xff0c;用于建模智能体&#xff08;agent&#xff09;在随机环境中做决策的问题。它假设环境的状态转换具有马尔可夫性质&#xff0c;即未来的状态只依赖于当前状…...

【RabbitMQ】核心概念和工作流程

文章目录 RabbitMQ 工作流程流程图 Producer 和 ConsumerConnecting 和 ChannelVirtual hostQueueExchangeRabbitMQ 工作流程 RabbitMQ 工作流程 流程图 RabbitMQ 就是一个生产者/消费者模型 Producer 就是生产者、Consumer 就是消费者Broker 是 RabbitMQ 服务器生产者和消费…...

Windows 操作系统 - Windows 10 磁盘管理无法为 C 盘选择扩展卷

Windows 10 磁盘管理无法为 C 盘选择扩展卷 在 Windows 10 的磁盘管理中&#xff0c;无法为 C 盘选择扩展卷&#xff08;选项灰色不可用&#xff09;&#xff0c;主要原因是未分配空间没有紧邻 C 盘的右侧 补充&#xff1a;Windows 10 磁盘管理打开方式 1. 按下快捷键【Win …...

数据结构——双向链表

首先我们要介绍一下链表的分类 链表的分类 链表说明&#xff1a; 虽然有这么多种链表结构&#xff0c;但是我们实际中用的还是两种结构&#xff1a;单链表&#xff08;单向不带头不循环&#xff09;和 双向带头循环链表 。 单链表&#xff08;单向不带头不循环&#xff09;&…...

Git报错remote: Verify fatal: Authentication failed for ***

解决 Git 拉取代码时报错&#xff1a;fatal: Authentication failed 在使用 Git 时&#xff0c;执行如下命令&#xff1a; git pull origin master出现报错&#xff1a; remote: Verify fatal: Authentication failed for ***一、问题原因分析 1. 使用 HTTP 协议访问&#…...

八、自动化函数

1.元素的定位 web自动化测试的操作核心是能够找到页面对应的元素&#xff0c;然后才能对元素进行具体的操作。 常见的元素定位方式非常多&#xff0c;如id,classname,tagname,xpath,cssSelector 常用的主要由cssSelector和xpath 1.1 cssSelector选择器 选择器的功能&#x…...

websoket 学习笔记

目录 基本概念 工作原理 优势 应用场景 HTTP协议与 webSoket协议之间的对比 消息推送场景 1. 轮询&#xff08;Polling&#xff09; 2. 长轮询&#xff08;Long Polling&#xff09; 3. 服务器发送事件&#xff08;Server-Sent Events, SSE&#xff09; 4. WebSocket…...

正版金币捕鱼海洋管家APP源码结构解析与运行环境说明

这是一款基于成熟运营逻辑开发的休闲类互动娱乐游戏《海洋管家》&#xff0c;采用金币流通体系&#xff0c;双端源码完整&#xff0c;结构清晰&#xff0c;适合用于结构学习、本地部署测试或功能参考。 整体玩法围绕捕鱼为主线&#xff0c;并融合了排行榜、VIP、签到、道具商城…...

大语言模型深度思考与交互增强

总则&#xff1a;深度智能交互的全面升级 在主流大语言模型&#xff08;LLM&#xff09;与用户的每一次交互中&#xff0c;模型需于回应或调用工具前&#xff0c;展开深度、自然且无过滤的思考进程。当模型判断思考有助于提升回复质量时&#xff0c;必须即时进行全方位的思考与…...

Vue.js 项目中 vue.config.js 常用配置项解析

Vue.js 项目中 vue.config.js 常用配置项解析 摘要 在 Vue CLI 创建的项目中&#xff0c;vue.config.js 是核心配置文件&#xff0c;用于定制化构建、开发和部署流程。本文详细解析了该文件的常用配置项&#xff0c;包括基础路径、开发服务器、Webpack 配置、CSS 预处理、插件…...

Javascript逗号操作符

这段代码是一个使用了生成器函数&#xff08;Generator Function&#xff09;的无限循环&#xff08;for (;;)&#xff09;&#xff0c;内部通过switch语句控制流程。代码中有很多逗号分隔的语句&#xff0c;这其实是利用了JavaScript的逗号操作符&#xff08;comma operator&a…...

windows系统安装驱动、cuda和cudnn

一、首先在自己的电脑里安装了nvidia的独立显卡 显卡的查找方式&#xff1a; CtrlShiftEsc打开任务管理器&#xff0c;点击性能&#xff0c;点击GPU 0查看显卡型号&#xff0c;如下图所示&#xff1a; 只要电脑中有nvidia的独立显卡&#xff0c;就可以暗转显卡驱动、cuda和cu…...

常见的 14 个 HTTP 状态码详解

文章目录 一、2xx 成功1、200 OK2、204 No Content3、206 Partial Content 二、3xx 重定向1、301 Moved Permanently2、302 Found3、303 See Other注意4、Not Modified5、307 Temporary Redirect 三、4xx 客户端错误1、400 Bad Request2、401 Unauthorized3、403 Forbidden4、4…...

DAY 44 leetcode 28--字符串.实现strStr()

题号28 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 我的解法 双指针&#xff0c;slow定位&…...

Nginx用途以及好处:

反向代理&#xff1a; 1、提高访问速度 2、进行负载均衡&#xff1a;所谓负载均衡&#xff0c;就是把大量的请求按照我们指定的的方式均衡的分配给集群中的每台服务器(不使用nginx前端会固定的访问某一台服务器 加入nginx分配到多台服务器) 3、保证后端的安全 服务器一般部署在…...

打造可控可测的星座网络:IPLOOK低轨通信仿真平台搭建实践

在低轨卫星通信迅猛发展的趋势下&#xff0c;空天地一体化网络正逐步成为新一代信息基础设施的核心组成。作为移动核心网领域的技术引领者&#xff0c;IPLOOK依托在5G核心网、NTN&#xff08;非地面网络&#xff09;和卫星通信仿真方面的技术优势&#xff0c;率先构建了自主可控…...

火车头采集动态加载Ajax数据(无分页瀑布流网站)

为了先填充好数据在上线&#xff0c;在本地搭建了一个网站&#xff0c;并用火车头采集数据填充到里面。 开始很上手&#xff0c;因为找的网站的分类中是有分页的。很快捷的找到页面标识。 但是问题来了&#xff0c;如今很多网站都是采用的Ajax加载数据&#xff0c;根本没有分…...

笔记:代码随想录算法训练营day67:Floyd 算法精讲、A * 算法精讲 (A star算法) 严重超时完结,不过,撒花

学习资料&#xff1a;代码随想录 Floyd 算法精讲 卡码网&#xff1a;97. 小明逛公园 首先明确floyd算法解决的是多源最短路径问题&#xff0c;对边的权的正负值没有要求&#xff0c;而且是动态规划的思想 五部曲&#xff1a; 定义&#xff1a;grid[i][j][k]表示从i出发到j…...