1. 背景与需求

1.1 什么是Starter? Spring Boot的起步依赖(Starter)是一种特殊的依赖描述符,用于简化Spring应用的依赖管理和自动配置。官方文档将Starter定义为“一组方便的依赖描述符”,开发者只需引入对应的Starter,就能“一站式”获得所需的Spring技术栈和默认配置。例如,spring-boot-starter-web包含了Spring MVC、Jackson等常用库,并在启动时自动完成相关配置,使开发者无需逐个添加依赖或手动编写冗长配置。

1.2 为什么需要自定义Starter? 在企业级开发中,往往存在一些跨项目复用的通用功能(如日志拦截、权限校验、消息通知等),如果在每个项目中单独实现,不仅代码重复,维护成本也高。自定义Starter可以将这些公共功能、依赖和配置封装成一个可复用的模块,提高代码重用性配置一致性。例如,通过自定义Starter,可以统一项目的外部依赖和默认行为,开发者只需简单地引入Starter即可获得完整功能。正如实践中所示,自定义Starter的主要优势包括模块化设计、配置简化快速集成等。举例来说,一个团队在多个微服务中都需要短信验证码发送功能,此时创建一个短信服务Starter就能避免在每个微服务中重复编码,只需在项目中添加依赖即可开箱即用。

1.3 典型应用场景。 自定义Starter最常见的应用场景包括:

  • 企业通用功能封装:如短信/邮件通知、缓存封装、数据库读写分离等。通过Starter把这些功能在各项目间共享。

  • 业务中间件集成:例如消息队列(RabbitMQ、Kafka)、分布式ID生成、日志拦截(AOP切面)等逻辑可封装为Starter。

  • 权限及安全模块:统一的鉴权、访问控制或安全策略也可以打包为Starter,保证各系统的一致性。

  • 微服务公共组件:例如全局异常处理、监控拦截器、统一配置客户端等。Spring Boot官方及社区提供的许多Starter(如Web、JPA、Cloud Config等)也正是基于这些需求而设计。

综上,自定义Starter通过约定大于配置的理念,为团队提供了便利——只需添加依赖即可获得完整功能配置,极大提升开发效率。

2. 核心原理

2.1 Spring Boot自动装配机制解析。 Spring Boot的自动装配机制(Auto-Configuration)是Starter能够开箱即用的基础。其实现原理是:Spring Boot在启动时通过SpringFactoriesLoader扫描所有Jar包下的META-INF/spring.factories(或新版本中的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports),将其中列出的自动配置类(@Configuration)加载到应用上下文中。这些自动配置类一般带有各种@Conditional注解(如@ConditionalOnClass@ConditionalOnMissingBean等),用于在特定条件下动态注册Bean。例如,Spring Boot常在自动配置类上使用@ConditionalOnClass检查类路径中是否存在相关库,如果存在才启用该自动配置;而@ConditionalOnMissingBean则保证在用户未自定义相同Bean时才注册默认Bean。这种基于条件的加载确保了自动配置的灵活性和安全性,避免与业务代码发生冲突。

在启动阶段,SpringApplication.run()会触发自动装配流程:Spring Boot首先创建一个应用上下文,然后调用SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration, classLoader)读取所有自动配置类的全限定名,依次加载这些配置类并解析@Conditional注解。只有当所有条件都满足时,自动配置类中的@Bean方法才会被执行,相关Bean才会注入到容器。这一机制使得我们无需手动实例化对象或显式配置,Starter所提供的组件即可被自动发现并注入到应用中。

2.2 spring.factoriesAutoConfiguration.imports的演进。 早期Spring Boot(2.x以前)使用META-INF/spring.factories文件来注册自动配置类:在该文件中以org.springframework.boot.autoconfigure.EnableAutoConfiguration键列出所有自动配置类。例如:

# spring.factories示例(Spring Boot 2.x)
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.starter.CustomAutoConfiguration,\
com.example.starter.CustomWebAutoConfiguration

Spring Boot启动时会自动加载这些类。自Spring Boot 2.7起,引入了新的注册机制,允许在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中列出自动配置类,同时仍对旧方式提供兼容。而在Spring Boot 3.0及以上版本中,官方已移除通过spring.factories注册自动配置的支持,仅推荐使用AutoConfiguration.imports文件。新文件路径为:

src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

内容就是自动配置类的全限定名列表。这样做可以简化配置文件的格式,并避免spring.factories文件过度臃肿。因此,自定义Starter在支持Spring Boot 3.x时,应使用AutoConfiguration.imports;若需要兼容Spring Boot 2.x,建议同时保留spring.factories配置。

2.3 条件化配置注解的底层实现。 Spring Boot提供了丰富的条件注解(@ConditionalOnClass@ConditionalOnMissingBean@ConditionalOnProperty@ConditionalOnResource等),用于控制自动配置类或Bean的加载与否。这些注解本质上都是基于Spring核心的@Conditional机制实现的:Spring在解析配置类时,会调用对应的Condition接口逻辑来判断条件是否成立。例如,@ConditionalOnClass会检查指定的类是否存在于类路径中;其底层通过Spring的注解元数据解析器(基于ASM技术)读取注解属性,从而在不实际加载类的情况下判断类是否可用。而@ConditionalOnProperty则根据Environment中的配置属性值来决定加载,这使得我们可以通过配置文件动态打开或关闭某些Starter功能。再如,@ConditionalOnMissingBean会在容器中查找指定类型的Bean,只有找不到时才创建默认Bean,从而允许用户自定义Bean来覆盖自动配置。通过这些条件注解的叠加使用,自动装配机制能够智能地对环境进行自适应,大幅简化配置和避免冲突。这些实现细节藏在Spring Boot的自动配置源码中(如org.springframework.boot.autoconfigure.condition包),但对使用者来说,只需理解其使用场景即可编写灵活的Starter。

3. 自定义Starter开发步骤

下面我们通过一个示例来演示自定义Starter的全流程。假设要开发一个“hello-starter”,它提供一个HelloService,通过配置文件可定制欢迎消息。

3.1 创建Maven项目并引入依赖

首先,新建一个Maven项目作为Starter的主体。建议项目<artifactId>以功能名加后缀-spring-boot-starter命名,例如hello-spring-boot-starter。在pom.xml中,引入Spring Boot自动装配相关依赖,例如:

<project ...><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>hello-spring-boot-starter</artifactId><version>1.0.0</version><!-- 父POM使用Spring Boot Starter Parent --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.0</version></parent><dependencies><!-- 引入自动配置支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><!-- 可选:引入配置元数据生成器,帮助IDE对@ConfigurationProperties提供自动补全(可标记为optional) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency></dependencies>
</project>

说明: spring-boot-autoconfigure 依赖让Starter能挂钩到自动装配体系;spring-boot-configuration-processor 用于在编译期生成配置属性提示元数据,开发者在使用时可获得IDE的自动提示。请根据实际需求选择Spring Boot版本,若需要支持Spring Boot 3.x,可将父POM版本设置为3.x

3.2 编写自动配置类与属性绑定类

自动配置类示例: 在代码中创建一个配置类,例如HelloServiceAutoConfiguration,用于注册Starter提供的Bean。示例代码:

@Configuration
@EnableConfigurationProperties(HelloProperties.class)
@ConditionalOnClass(HelloService.class)
public class HelloServiceAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic HelloService helloService(HelloProperties props) {// 使用配置属性初始化Servicereturn new HelloService(props.getMsg());}
}

其中:

  • @Configuration声明这是一个配置类。

  • @EnableConfigurationProperties(HelloProperties.class)启用属性绑定,Spring Boot会将带@ConfigurationProperties注解的HelloProperties加载为Bean,并从配置文件中将前缀hello的属性注入到该对象中。

  • @ConditionalOnClass(HelloService.class)表示只有当类路径中存在HelloService时才启用此自动配置,避免所需依赖缺失导致异常。

  • @Bean @ConditionalOnMissingBean表示注册HelloService Bean且仅当容器中尚未存在同名或同类型的Bean时才生效,允许用户自行覆盖默认实现。

  • 方法内部通过HelloProperties获取外部配置的值,为HelloService实例提供定制化参数。

配置属性类示例: 创建一个用于绑定配置的Java类,例如:

@ConfigurationProperties(prefix = "hello")
public class HelloProperties {private String msg = "Hello, World!";// getter & setter
}

@ConfigurationProperties(prefix="hello")注解将匹配配置文件中以hello开头的属性,将其映射到类的字段上。例如,如果在application.yml中写入:

hello:msg: "你好,世界!"

HelloPropertiesmsg字段会被注入为“你好,世界!”。spring-boot-configuration-processor依赖会在编译时为此类生成元数据文件,IDE会根据prefix给出智能提示。以上步骤完成后,我们的自动配置类就能自动读取并使用外部配置值。

3.3 配置spring.factoriesAutoConfiguration.imports

为了让Spring Boot应用扫描到我们的自动配置类,需要在src/main/resources下创建元数据文件:

  • 对于Spring Boot 2.x(尤其是2.6及以前)版本,在META-INF/spring.factories中添加:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.example.hello.HelloServiceAutoConfiguration
    

     

  • 对于Spring Boot 2.7+ / 3.x版本,应在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中列出自动配置类:

    com.example.hello.HelloServiceAutoConfiguration
    

使用AutoConfiguration.imports文件的方式是Spring Boot新版本的要求。前者方式在3.0后已不再支持,但若需要兼容,建议同时维护两个文件。Spring Boot启动时会读取这些文件,发现并加载列出的配置类。

3.4 打包与发布Starter

完成代码后,可以使用Maven将Starter打包为JAR。执行 mvn clean install 会编译并将JAR安装到本地Maven仓库(~/.m2/repository)。完成安装后,其他项目即可通过添加依赖的方式引入Starter:

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

如果希望团队成员或CI环境都能获取该Starter,应将其发布到远程仓库(如私有的Nexus/Artifactory)。在pom.xml中配置<distributionManagement>指向仓库地址,并执行mvn deploy即可将构建产物上传。同理,若希望公开发布到Maven Central,还需要按Sonatype要求添加签名等配置(略)。总之,发布过程与普通Maven项目一致,将生成的JAR交给目标仓库管理即可供其他项目消费。

4. 源码解析

4.1 SpringApplication启动过程中的自动配置加载。 Spring Boot应用启动时,SpringApplication会创建并刷新ApplicationContext,期间会通过SpringFactoriesLoader加载自动配置类。具体来看,Spring Boot会使用EnableAutoConfiguration作为key,从所有依赖的JAR包中查找spring.factoriesAutoConfiguration.imports文件。然后将每个自动配置类按需注册到上下文。当条件均满足时,自动配置类中的@Bean方法会被调用,生成对应的Bean并加入到容器。这一过程在官方文档中总结为:“Spring Boot在启动时从AutoConfiguration.imports(或旧版的spring.factories)中发现自动配置类,校验各个条件后,将相应的Bean装配到应用上下文中。”换言之,自定义Starter的自动配置类一旦正确注册,就如同Spring容器自带的Bean一样被自动加载,没有任何额外手动干预。

4.2 @ConfigurationProperties绑定配置的实现原理。 Spring Boot通过@ConfigurationProperties和相关后置处理器实现了配置与Java对象的绑定。当在自动配置类上使用@EnableConfigurationProperties(HelloProperties.class)时,Spring Boot会将HelloProperties注册为一个Bean。启动时,ConfigurationPropertiesBindingPostProcessor会扫描环境(Environment)中的属性,将hello.*前缀的配置注入到HelloProperties实例中。这一机制依赖于Spring对注解元数据的处理,背后使用了Binder或松耦合的元数据解析器,将标准的application.yml/properties映射到对象字段。例如,前述示例中hello.msg=…就会自动赋值给HelloProperties.msg。如果配置格式错误或前缀不匹配,则注入会失败,此时Spring会在启动时抛出异常并提示配置问题。因此,在设计Starter时要确保prefix设置正确,并在需要时通过配置处理器生成元数据(以提供提示)。

4.3 条件化注解的源码分析。 Spring Boot的条件注解实际是由Spring核心的@Conditional支持的。当应用上下文解析@Configuration类时,Spring会调用对应的Condition逻辑。以@ConditionalOnClass为例,它的底层实现会检查指定类是否存在于类路径中;其注解元数据可以直接使用类名字符串,由Spring使用ASM库解析即可。如果条件不满足,则Spring会跳过该配置类或Bean的加载。类似地,@ConditionalOnMissingBean通过检查容器中的Bean定义来决定是否注册新Bean。@ConditionalOnProperty则读取Environment的属性值,与指定条件比较。Spring Boot还提供了更多复杂条件(如Web应用存在与否、特定资源文件存在与否等),都依赖于Spring的条件机制。开发者在编写自动配置时,可自由组合这些注解,从而精确控制Starter的激活时机。例如,可以使用@ConditionalOnProperty来实现按需启用,只有在配置文件开启开关时才加载相关Bean。总体而言,条件注解的实现逻辑分散在Spring Boot源码(org.springframework.boot.autoconfigure.condition包)中,但使用时只要注重含义即可。

5. 使用示例

假设已经将自定义Starter发布成功,下面演示在一个Spring Boot应用中引入并验证该Starter功能。

5.1 引入自定义Starter。 在目标项目的pom.xml中添加Starter依赖:

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

然后在应用主类或任意@SpringBootApplication所在的类中,直接使用Starter提供的组件。例如,可以注入HelloService

@SpringBootApplication
public class DemoApplication implements CommandLineRunner {@Autowiredprivate HelloService helloService;public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Overridepublic void run(String... args) {System.out.println(helloService.sayHello());}
}

只要Starter和自动配置正确,Spring Boot会自动扫描并注册HelloService Bean,无需额外配置。

5.2 通过application.yml配置自定义属性。 假设HelloService会使用HelloProperties里的msg属性,那么在src/main/resources/application.yml中可以配置:

hello:msg: "欢迎使用自定义Starter!"

配置完成后,重启应用时,helloService.sayHello()将使用以上自定义消息作为输出。类似地,如果在自动配置类中使用了@ConditionalOnProperty来控制开关,也可在此处设置开关属性(如hello.enabled=true)来决定是否启用该Starter。

5.3 验证Starter功能。 运行目标应用,如果控制台输出了Starter中定义的欢迎消息(或触发了日志拦截、权限校验等功能),说明自定义Starter已正确生效。例如,在日志方面,可在自动配置中定义一个AOP切面,在配置文件中开启时统一记录请求日志;在权限校验方面,可定义一个拦截器在每次请求前进行鉴权。通常,我们只需编写Starter测试代码或@SpringBootTest单元测试来验证其行为即可。在实际业务中,也可以通过增加日志或调试级别(logging.level.org.springframework=DEBUG)观察自动配置报告,以确认Starter中的组件是否已经装配到容器。

6. 常见问题与优化

6.1 类路径冲突的解决方案。 自定义Starter引入依赖时,可能会与项目中已有依赖产生版本冲突或重复类。如果Starter中包含了大量第三方库,一旦这些库版本与应用自身版本不符,可能导致类冲突或NoClassDef错误。为避免此类问题,最佳实践是将可选的依赖声明为providedoptional,即只在编译时使用,不打包进最终Jar。例如,如果Starter中需要使用Jackson或Spring Web,可在Starter的pom.xml中将其依赖标记为<optional>true</optional><scope>provided</scope>,这样使用Starter的应用可以自行选择合适版本。同时,应仔细管理Spring Boot的版本兼容性,Starter的spring-boot-autoconfigure版本尽量与目标应用一致。遇到冲突时,可通过<exclusions>剔除Starter传递的冲突依赖,并使用spring.autoconfigure.exclude排除不需要的自动配置类。

6.2 配置加载失败的排查方法。 如果Starter所提供的配置属性没有生效,常见原因包括:属性前缀填写错误、@EnableConfigurationProperties未生效或配置文件位置不正确等。排查时可先检查application.yml/properties的格式和前缀是否与@ConfigurationProperties匹配;确保自动配置类已被正确加载(可查看控制台输出的自动配置报告)。开启Spring Boot的调试模式(-Dspring-boot.run.arguments=--debug)可以查看所有自动配置类是否生效,并排查未加载的原因。此外,请确认在Spring Boot 3.x环境中是否正确使用了AutoConfiguration.imports,以及Starter的包名、类名没有拼写错误。对于更深层问题,可编写测试类并使用@SpringBootTest,观察应用上下文中是否包含期待的Bean。

6.3 性能优化建议。 虽然自动装配带来了便利,但不必要的Bean也可能影响启动性能。可以通过优化条件加载来提升效率:

  • 按需加载:利用@ConditionalOnProperty等条件,仅在确实需要时才加载相应配置和Bean。

  • 延迟初始化:在Spring Boot 2.2及以上版本,可以设置spring.main.lazy-initialization=true,让Bean在真正被使用时才创建,减少启动耗时。

  • Spring Boot自定义Starter:从原理到实战全解析控制自动配置顺序:如果多个Starter存在依赖关系,可使用@AutoConfigureBefore@AutoConfigureAfter来指定加载顺序,避免不必要的覆盖或重复加载。

  • 剔除冗余依赖:Starter中不应包含过多和业务无关的依赖,尽可能精简打包内容。参考发布打包时的建议,例如避免打包日志框架或数据库驱动,让应用自行管理这些通用依赖。

通过上述方法,可以让自定义Starter在保证功能的同时,尽量减少对应用性能的影响。

7. 实际业务场景

7.1 微服务中统一异常处理模块。 在微服务架构中,常常需要在各个服务中采用一致的异常响应格式。可以通过自定义Starter来封装全局异常处理逻辑:例如,实现一个带有@ControllerAdvice注解的统一异常处理类,并将其包含在Starter中。当各微服务引入该Starter后,在控制器抛出异常时,统一的@ExceptionHandler就会生效,返回标准化的错误响应(如特定格式的JSON)。这种方式下,开发人员无需在每个服务中手动编写重复的异常处理代码,只需关心业务逻辑即可,极大提升了代码复用性和可维护性。

7.2 企业级通用工具类封装: 许多企业级项目都需要集成短信发送、邮件通知、分布式ID生成等服务。以短信服务为例,在“自定义Starter:简化短信服务集成”案例中,通过编写SmsAutoConfigurationSmsProperties,开发者能实现一个「短信Starter」,在项目中引用即可简单地通过配置调用短信接口。同理,邮件通知、支付SDK、日志上报等通用工具也可采用相同的方式打包。此类Starter封装了与第三方系统交互的复杂细节(如API客户端初始化、加密校验等),让业务开发者专注于配置参数,从而提高开发效率并保证了企业架构的一致性。

通过上述示例可见,自定义Starter使得“重复性劳动”变为可复用的模块,在实际项目中价值非常显著

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/92591.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/92591.shtml
英文地址,请注明出处:http://en.pswp.cn/web/92591.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安宝特方案丨工业AR+AI质检方案:致力于提升检测精度与流程效率

据IDC预测&#xff0c;2025年中国工业AI质检市场规模将达62亿元&#xff0c;年复合增长率28.5%&#xff0c;新能源、消费电子、高端装备三大领域贡献超70%市场份额。这一数据印证了AI质检已从可选技术升级为制造业降本增效的生存刚需。当前制造业质检环节正面临&#xff1a;精度…

AudioLLM

参考链接&#xff1a;https://mp.weixin.qq.com/s/cscrUn7n_o6PdeQRzWpx8g 视频教程&#xff1a;https://www.bilibili.com/video/BV1LGbozkEDY 模型代码&#xff1a;https://github.com/boson-ai/higgs-audio 如果是两个模型加在一起&#xff1a;一个语言模型&#xff0c;一个…

基于 CEP 引擎的算法拆单与调度实践—基础篇

在金融市场中&#xff0c;大额订单的一次性交易可能会对市场价格产生较大冲击&#xff0c;导致交易成本增加。例如&#xff0c;大额买入订单可能会迅速推高股价&#xff0c;使后续买入成本上升&#xff1b;大额卖出订单则可能打压股价&#xff0c;造成资产贱卖。拆单算法通过将…

开源 C# TCP 通信框架 SocketDJ 发布:轻量、免费、可扩展

前言市面上的网络通信框架琳琅满目&#xff0c;功能强大者有之&#xff0c;但不少都存在功能闭源、商业收费、学习成本高等问题。作为一名热爱底层技术的开发者&#xff0c;我始终相信&#xff1a;基础通信能力应当简单、透明且免费。最近正好有项目需求&#xff0c;索性动手从…

移动机器人路径规划中ROS2中间件性能的研究综述

导读&#xff1a; 随着移动机器人在工业自动化、特种作业及智能服务领域的广泛应用&#xff0c;其路径规划能力越来越依赖机器人操作系统ROS2的通信性能。ROS2通过去中心化架构与数据分发服务中间件显著提升了系统可靠性&#xff0c;但动态复杂环境中路径规划对通信延迟、带宽…

【昇腾】Atlas 500 A2 智能小站制卡从M.2 SATA盘启动Ubuntu22.04系统,重新上电卡死没进系统问题处理_20250808

一、问题背景 Atlas 500 A2智能小站是华为基于20T 12G版本的Atlas 200I A2加速模块开发的面向广泛边缘应用场景的轻量边缘设备&#xff0c;具有超强计算性能、配置灵活、体积小、支持温度范围宽、环境适应性强、易于维护 管理等特点的产品。Atlas 500 A2智能小站主要应用在智能…

sigaction 中 sa_handler = SIG_IGN 的深度解析与应用实践

sigaction 中 sa_handler SIG_IGN 的深度解析与应用实践 核心意义&#xff1a;主动忽略信号 当 sa_handler 设置为 SIG_IGN 时&#xff0c;内核将完全丢弃指定的信号&#xff0c;不会&#xff1a; 执行默认行为调用任何处理函数中断进程的正常执行 这与 SIG_DFL&#xff08;默…

【LLM实战|langchain、qwen_agent】RAG高级

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?type=blog 0. 前言 RAG高级 1. RAG 高效召回方法 合理设置TOP-K 改进索引算法 -知识图谱 引入重排序 重排序模型 BGE-Rerank Cohere Rerank 混合检索 向量索引+关键词索引…

C++方向知识汇总(一)

关于单例模式1.什么是单例模式&#xff1f;答&#xff1a;单例模式是一种创建型设计模式&#xff0c;确保一个类在运行期间仅有一个实例&#xff0c;提供全局唯一的访问点2.单例模式的目的&#xff1f;答&#xff1a;避免重复创建资源消耗大的对象&#xff0c;例如日志系统、线…

学习:JS[8]本地存储+正则表达式

一.本地存储1.介绍将数据存储到用户浏览器当中设置、读取方便、页面刷新不丢失数据2.本地存储分类-localStoragea.语法(1)存储数据//存储数据 localStorage.setItem(键,值)如 localStorage.setItem(uname,哈哈)(2)获取数据//获取方式 都加引号 localStorage.getItem(键) localS…

C++算法练习:单词识别

做题记录&#xff1a;牛客习题&#xff1a;单词识别 相关题目代码已经提交到gitee中&#xff1a;楼田莉子 (riko-lou-tian) - Gitee.com喜欢请点个赞谢谢 目录 题目&#xff1a; C 字符函数头文件头文件&#xff1a;&#xff08;C 标准库&#xff09;核心函数功能说明&#…

从免费到盈利:Coze智能体1小时封装变现全流程指南——井云科技

在AI技术普惠的浪潮下&#xff0c;Coze等智能体平台让零代码开发者也能快速构建功能强大的AI助手。然而&#xff0c;许多创作者在完成智能体开发后&#xff0c;却面临“工具免费、成本自担”的困境——用户无限制调用导致算力成本飙升&#xff0c;想收费又缺乏成熟的支付与用户…

C++学习之STL学习:map/set

通过前面的学习&#xff0c;我们已经对C STL有了初步了解。然而&#xff0c;STL作为一个庞大复杂的体系&#xff0c;远不止这些内容。接下来&#xff0c;我们将深入探讨STL中的另外两个重要组件——map和set。 作者的个人gitee&#xff1a;楼田莉子 (riko-lou-tian) - Gitee.co…

[学习] CORDIC算法详解:从数学原理到反正切计算实战

CORDIC算法详解&#xff1a;从数学原理到反正切计算实战 文章目录CORDIC算法详解&#xff1a;从数学原理到反正切计算实战引言一、数学原理二、求解流程&#xff08;旋转模式&#xff09;三、典型应用场景四、反正切计算示例&#xff08;Python实现&#xff09;五、算法流程可视…

3款强力的Windows系统软件卸载工具

1、Geek 下载地址&#xff1a;https://download.csdn.net/download/weixin_42203093/91625765 Geek Uninstaller 是一款专业的 Windows 软件卸载工具&#xff0c;主要用于卸载软件并清理残留垃圾&#xff1a; 特点 体积小巧便携&#xff1a;软件体积约为 1.7M&#xff0c;是单…

AcWing 4579. 相遇问题

这道题做个今天的结尾 比较简单 正在备战csp吗&#xff0c;正好刷一下 难度&#xff1a;简单时/空限制&#xff1a;1s / 256MB总通过数&#xff1a;1738总尝试数&#xff1a;2584来源&#xff1a; CSP-J 2022 模拟赛 原题链接 4579. 相遇问题 - AcWing题库 题目描述 一…

基于clodop和Chrome原生打印的标签实现方法与性能对比

今天想看看&#xff0c;基于clodop和Chrome原生打印的标签实现方法与性能对比。先看看DeepSeek关于这个问题的回答&#xff01; CloudPrint 和 Chrome 原生打印的区别 基本概念差异 CloudPrint (Clodop) 是基于云的打印服务解决方案需要安装专门的客户端程序支持跨平台、跨设备…

百度网盘如何做到下载速度最快?OpenSpeedy绿色安装版下载,开源免费网盘加速

下载地址获取点击这里打开&#xff1a;OpenSpeedy下载地址 打开解压后的文件夹&#xff0c;找到【OpenSpeedy.exe】应用程序&#xff0c;右键选择【以管理员身份运行】。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 主要特性&#xff1a; 免费开源蛮…

科技云报到:热链路革命:阿卡 CRM 的 GTM 定位突围

科技云报道原创。在企业数字化的工具箱里&#xff0c;“CRM” 一词早已不是 “全流程客户管理” 的代名词&#xff0c;而是从营销获客到客户信息沉淀&#xff0c;再到长期关系维护&#xff0c;仿佛要包揽从线索到复购的所有环节。但成立仅两年半的阿卡 CRM&#xff0c;却在实践…

什么是Graphical Abstract

什么是Graphical Abstract 现在都需要用Graphical Abstract&#xff0c;新加的好像。图形摘要&#xff08;Graphical Abstract&#xff09;是学术论文中一种以可视化方式浓缩呈现研究核心内容的图表&#xff0c;它通过简洁的图形、流程图、示意图或组合视觉元素&#xff0c;直观…