解决Spring Boot多模块自动配置失效问题

前言

在Spring Boot多模块项目中,模块间配置不生效是一个复杂但可解决的问题,尤其涉及自动配置类、依赖冲突、条件注解以及IDE配置。


一、问题背景与场景

1.1 场景描述

假设存在两个模块:

  • 模块A:提供通用配置(如跨域配置、全局异常处理、拦截器)。
  • 模块B:引用模块A,但模块A的配置未生效(如跨域配置无效、异常处理器未捕获异常)。

1.2 核心问题

  1. 自动配置类未被加载:模块A的@AutoConfiguration类未在模块B中生效。
  2. 依赖冲突:第三方库间接引入了与模块A冲突的依赖(如日志框架版本不一致)。
  3. 条件注解限制:配置类因@ConditionalOnClass等条件未满足而跳过。
  4. 包扫描路径错误:模块B未扫描到模块A的包路径。

二、解决方案

2.1 步骤1:声明自动配置类

2.1.1 使用META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

在模块A的src/main/resources目录下创建以下路径:

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

文件内容为一行一个自动配置类的全限定名:

com.example.moduleA.config.ResourcesConfig
2.1.2 代码示例:自动配置类
// 模块A的ResourcesConfig.java
@AutoConfiguration
@ConditionalOnWebApplication(type = Type.SERVLET) // 仅在Servlet环境生效
public class ResourcesConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 全局性能拦截器registry.addInterceptor(new PlusWebInvokeTimeInterceptor()).addPathPatterns("/**") // 拦截所有路径.excludePathPatterns("/actuator/**"); // 排除监控端点}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 静态资源处理(如Swagger)registry.addResourceHandler("/docs/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");}/*** 跨域配置(通过@Bean注册)*/@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.setAllowCredentials(true);config.addAllowedOriginPattern("*"); // 允许所有源config.addAllowedHeader("*"); // 允许所有请求头config.addAllowedMethod("*"); // 允许所有HTTP方法config.setMaxAge(1800L); // 预检请求缓存时间UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}
}

2.2 步骤2:确保全局异常处理器生效

2.2.1 全局异常处理器代码
// 模块A的GlobalExceptionHandler.java
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(HttpRequestMethodNotSupportedException.class)public ResponseEntity<String> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {log.error("请求地址'{}', 不支持'{}'请求", request.getRequestURI(), e.getMethod());return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED).body("请求方法不支持: " + e.getMethod());}@ExceptionHandler(ServiceException.class)public ResponseEntity<ErrorResponse> handleServiceException(ServiceException e, HttpServletRequest request) {log.error("业务异常: {}", e.getMessage());return ResponseEntity.status(e.getStatusCode()).body(new ErrorResponse(e.getCode(), e.getMessage()));}@ExceptionHandler(Exception.class)public ResponseEntity<String> handleGlobalException(Exception e) {log.error("全局异常: {}", e.getMessage(), e);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("系统内部错误");}private static class ErrorResponse {private final int code;private final String message;public ErrorResponse(int code, String message) {this.code = code;this.message = message;}}
}

2.3 步骤3:检查依赖传递与冲突

2.3.1 排除间接依赖冲突

假设模块B引用了mybatis-spring-boot-starter,而该依赖间接引入了spring-boot-starter-logging(导致日志框架冲突)。需在POM中排除:

<!-- 模块B的pom.xml -->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.1</version><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions>
</dependency>
2.3.2 检查依赖树

使用Maven或Gradle命令查看依赖树:

# Maven
mvn dependency:tree | grep -i logback# Gradle
./gradlew dependencies --configuration compileClasspath

2.4 步骤4:确保包扫描路径正确

2.4.1 显式指定扫描路径

在模块B的启动类中设置scanBasePackages

// 模块B的启动类
@SpringBootApplication(scanBasePackages = {"com.example.moduleA.config","com.example.moduleA.handler","com.example.moduleB.controller"}
)
public class ModuleBApplication {public static void main(String[] args) {SpringApplication application = new SpringApplication(ModuleBApplication.class);application.setAdditionalProfiles("dev"); // 激活开发环境配置application.run(args);}
}
2.4.2 包结构优化

确保模块A的包路径是模块B启动类的子包:

com.example
├── moduleA
│   ├── config
│   │   └── ResourcesConfig.java
│   └── handler
│       └── GlobalExceptionHandler.java
└── moduleB├── controller│   └── UserController.java└── ModuleBApplication.java

2.5 步骤5:验证条件注解

2.5.1 示例:基于属性的条件
// 模块A的FeatureAutoConfiguration.java
@Configuration
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public class FeatureAutoConfiguration {@Beanpublic FeatureService featureService() {return new FeatureServiceImpl();}
}

application.yml中激活条件:

feature:enabled: true

2.6 步骤6:IDEA路径问题排查

2.6.1 确保目录结构正确
  • 错误路径:IDEA可能将META-INF/spring显示为META-INF.spring
  • 解决方法
    1. 删除错误路径。
    2. 右键src/main/resourcesNew → Directory → 输入META-INF/spring
    3. 创建AutoConfiguration.imports文件。

三、核心知识点详解

3.1 Spring Boot自动配置机制

3.1.1 核心组件
  1. 条件注解
    • @ConditionalOnClass:类路径存在指定类时生效。
    • @ConditionalOnMissingBean:容器中无指定Bean时生效。
    • @ConditionalOnProperty:属性存在且符合条件时生效。
    • @ConditionalOnWebApplication:仅在Web环境生效。
  2. 自动配置类
    • 通过@AutoConfiguration标注,配合AutoConfiguration.imports文件声明。
  3. 加载流程
    • Spring Boot 2.x:通过spring.factories文件加载自动配置类。
    • Spring Boot 3.x:推荐使用AutoConfiguration.imports
3.1.2 新旧机制对比
特性spring.factories(旧)AutoConfiguration.imports(新)
文件路径META-INF/spring.factoriesMETA-INF/spring/org...AutoConfiguration.imports
格式需声明EnableAutoConfiguration直接列出类名,无需键值对
性能全局扫描,可能加载冗余配置按需加载,性能更优

3.2 依赖管理

3.2.1 排除依赖冲突
<!-- 模块B的pom.xml -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions>
</dependency>
3.2.2 引入必要依赖
<!-- 引入log4j2 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

3.3 条件注解进阶用法

3.3.1 组合条件
@Configuration
@ConditionalOnClass(RedisClient.class) // 类路径存在RedisClient
@ConditionalOnProperty(name = "redis.enabled", matchIfMissing = true) // 属性存在或未配置时生效
public class RedisAutoConfig {// 配置逻辑
}
3.3.2 优先级控制
@AutoConfiguration(after = AnotherConfig.class)
public class MyConfig {// 该配置类将在AnotherConfig之后加载
}

3.4 多模块包扫描

3.4.1 动态扫描策略
// 使用@Import动态导入配置类
@Import({DatabaseAutoConfiguration.class, LoggingAutoConfiguration.class})
public class ModuleBApplication {// ...
}

四、常见陷阱与解决方案

4.1 陷阱1:IDEA路径错误

  • 现象META-INF/spring目录被错误显示为META-INF.spring
  • 解决
    1. 删除错误路径。
    2. 右键src/main/resourcesNew → Directory → 输入META-INF/spring
    3. 重新创建AutoConfiguration.imports文件。

4.2 陷阱2:配置文件覆盖

  • 现象:模块B的application.yml覆盖模块A的配置。
  • 解决
    1. 将模块A的配置文件放置在src/main/resources/config/目录下。
    2. 在模块B中指定激活配置文件:
      spring:config:activate:on-profile: moduleA
      

4.3 陷阱3:未激活Profile

  • 现象:环境特定配置未生效。
  • 解决
    # 启动时指定Profile
    java -jar app.jar --spring.profiles.active=dev
    

4.4 陷阱4:Spring Boot 3.x兼容性问题

  • 现象spring.factories配置失效。
  • 解决
    1. 将配置迁移到新路径:
      # 模块A的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
      com.example.moduleA.config.ResourcesConfig
      com.example.moduleA.handler.GlobalExceptionHandler
      
    2. 参考我在网上看到的博客的说明。

五、验证配置生效的方法

5.1 启动日志检查

  • 日志级别
    logging.level.root=DEBUG
    
  • 关键日志
    Positive matches:- ResourcesConfig (com.example.moduleA.config.ResourcesConfig)- GlobalExceptionHandler (com.example.moduleA.handler.GlobalExceptionHandler)
    

5.2 Bean注入验证

// 模块B的测试类
@RestController
public class HealthCheckController {@Autowiredprivate CorsFilter corsFilter;@GetMapping("/health/cors")public String health() {return "CorsFilter: " + corsFilter.getClass().getName();}
}

5.3 跨域配置测试

5.3.1 测试步骤
  1. 发送带有Origin头的请求:
    curl -H "Origin: https://test.com" -X GET http://localhost:8080/api/test
    
  2. 预期响应头
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
    

5.4 异常处理器验证

5.4.1 测试业务异常
// 模块B的Controller
@RestController
public class TestController {@GetMapping("/test")public ResponseEntity<String> test() {throw new ServiceException("自定义异常", HttpStatus.BAD_REQUEST);}
}

预期响应

{"code": 400,"message": "自定义异常"
}

六、完整解决方案代码示例

6.1 模块A的POM配置

<!-- 模块A的pom.xml -->
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>

6.2 模块B的POM配置

<!-- 模块B的pom.xml -->
<dependencies><dependency><groupId>com.example</groupId><artifactId>moduleA</artifactId><version>1.0.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

6.3 模块B的启动类

// 模块B的启动类
@SpringBootApplication(scanBasePackages = {"com.example.moduleA.config","com.example.moduleA.handler","com.example.moduleB.controller"}
)
public class ModuleBApplication {public static void main(String[] args) {SpringApplication application = new SpringApplication(ModuleBApplication.class);application.setAdditionalProfiles("dev"); // 激活开发环境配置application.run(args);}
}

6.4 模块A的自动配置文件

# 模块A的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.moduleA.config.ResourcesConfig
com.example.moduleA.handler.GlobalExceptionHandler

七、总结与最佳实践(代码视角)

7.1 核心总结

  1. 自动配置类必须通过AutoConfiguration.imports显式声明
    • 例如:在模块A的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中列出所有自动配置类。
  2. Bean注册需通过@Bean或实现WebMvcConfigurer
    • CorsFilter通过@Bean注册,WebMvcConfigurer方法需在@AutoConfiguration类中实现。
  3. 包扫描路径必须覆盖所有模块
    • 模块B的启动类需显式扫描模块A的包路径。

7.2 最佳实践代码模板

7.2.1 模块A的自动配置类模板
@AutoConfiguration
@ConditionalOnClass(DispatcherServlet.class) // 依赖Servlet环境
public class ResourcesConfig implements WebMvcConfigurer {// 跨域、拦截器等配置@Beanpublic GlobalExceptionHandler globalExceptionHandler() {return new GlobalExceptionHandler(); // 手动注册异常处理器}
}
7.2.2 全局异常处理器模板
@Slf4j
@RestControllerAdvice(basePackages = {"com.example.moduleA", "com.example.moduleB"})
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ResponseEntity<String> handleGlobalException(Exception e) {log.error("全局异常: {}", e.getMessage(), e);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("系统内部错误");}
}

八、附录:工具与命令

8.1 依赖树分析

mvn dependency:tree

8.2 日志级别调试

java -jar app.jar --logging.level.root=DEBUG

8.3 模块间依赖验证

# Gradle检查依赖冲突
./gradlew dependencies --configuration compileClasspath

九、补充


1. @AutoConfiguration注解详解

1.1 基本概念

  • 定义
    @AutoConfiguration 是Spring Boot 3.x引入的注解,用于标记一个类为自动配置类,其作用是简化自动配置类的声明,无需在META-INF/spring.factories中手动注册。
  • 作用
    1. 自动注册到Spring容器:被@AutoConfiguration标注的类会被Spring Boot自动识别为自动配置类。
    2. 按需加载:结合条件注解(如@ConditionalOnClass),仅在满足条件时生效。
    3. 模块化配置:适用于多模块项目,将配置逻辑封装到独立模块中。

1.2 @AutoConfiguration与@Configuration的区别

特性@AutoConfiguration@Configuration
作用自动配置类,无需手动注册普通配置类,需通过其他方式注册
自动注册自动注册到Spring容器(需配合AutoConfiguration.imports需显式注册(如通过组件扫描或@Import
适用场景自动配置场景(如多模块共享配置)通用配置类(如自定义Bean)
是否需要额外配置需在AutoConfiguration.imports文件中声明无需额外配置(但需被Spring容器扫描)
依赖关系通常与@Conditional注解结合可独立使用,但需手动管理Bean依赖

1.3 @AutoConfiguration的使用场景

场景1:多模块共享配置
// 模块A的ResourcesConfig.java
@AutoConfiguration
@ConditionalOnWebApplication(type = Type.SERVLET)
public class ResourcesConfig implements WebMvcConfigurer {// 跨域配置、拦截器等
}
  • 关键点
    • 通过@AutoConfiguration标记为自动配置类。
    • 在模块A的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中声明该类。
    • 模块B引用模块A后,无需手动导入,Spring Boot会自动加载。
场景2:替代旧版spring.factories
# Spring Boot 2.x的spring.factories(需手动注册)
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.moduleA.config.ResourcesConfig,\
com.example.moduleA.handler.GlobalExceptionHandler
  • Spring Boot 3.x的改进
    使用@AutoConfiguration + AutoConfiguration.imports文件,无需维护冗长的spring.factories

2. @Bean注解详解

2.1 基本概念

  • 定义
    @Bean 是Spring框架的核心注解,用于将方法返回的对象注册为Spring容器管理的Bean
  • 作用
    1. 显式声明Bean:开发者通过方法定义Bean的创建逻辑。
    2. 依赖注入:方法参数支持依赖注入(如@Autowired)。
    3. 灵活控制:可指定Bean作用域、初始化方法、条件等。
    4. 作用域控制:通过@Scope指定Bean的作用域(如singleton、prototype)。

2.2 @Bean的使用场景

场景1:定义基础Bean
@Configuration
public class DataSourceConfig {@Bean@ConditionalOnMissingBean(DataSource.class) // 仅当容器中没有DataSource时生效public DataSource dataSource() {HikariDataSource ds = new HikariDataSource();ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");return ds;}
}
  • 关键点
    • 通过@BeandataSource()方法返回的HikariDataSource注册为Bean。
    • 结合@ConditionalOnMissingBean避免与用户自定义Bean冲突。
场景2:注册第三方库Bean
@Configuration
public class JsonConfig {@Beanpublic ObjectMapper objectMapper() {ObjectMapper mapper = new ObjectMapper();mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));return mapper;}
}
  • 关键点
    • 将第三方库的ObjectMapper注册为Spring Bean,方便全局使用。
场景3:作用域控制
@Bean
@Scope("prototype") // 每次请求创建新实例
public MyPrototypeBean prototypeBean() {return new MyPrototypeBean();
}

3. @Configuration与@Bean的协作关系

3.1 基础配置类结构

@Configuration // 标记为配置类
public class MyAutoConfiguration {@Bean // 定义Beanpublic MyService myService() {return new MyServiceImpl();}
}
  • 关键点
    • @Configuration是配置类的“身份标识”。
    • @Bean是配置类中定义Bean的“工具”。

4. 为什么必须使用@AutoConfiguration?能否用@Configuration替代?

4.1 必须使用@AutoConfiguration的情况
  • 场景:在多模块项目中,模块A的配置需被模块B自动加载
  • 原因
    1. @AutoConfiguration配合AutoConfiguration.imports文件,无需手动注册
    2. 如果仅用@Configuration,需通过以下方式显式加载:
      • 在模块B的启动类中指定扫描路径。
      • 通过@Import(ResourcesConfig.class)导入。
      • spring.factories中注册(Spring Boot 2.x方式)。
  • 结论:在Spring Boot 3.x中,@AutoConfiguration是更简洁的解决方案。
4.2 @Configuration的替代方案
// 方案1:在模块B启动类中显式扫描模块A的包
@SpringBootApplication(scanBasePackages = {"com.example.moduleA", "com.example.moduleB"})
public class ModuleBApplication { ... }// 方案2:使用@Import导入配置类
@Configuration
@Import(ResourcesConfig.class)
public class ModuleBConfig { ... }
  • 缺点
    • 需手动维护包路径或导入关系,耦合性更高
    • 不具备条件化加载能力(除非手动添加@Conditional注解)。

5. 示例代码中的关键注解解析

5.1 ResourcesConfig示例
@AutoConfiguration
@ConditionalOnWebApplication(type = Type.SERVLET)
public class ResourcesConfig implements WebMvcConfigurer {@Beanpublic CorsFilter corsFilter() { ... }@Overridepublic void addInterceptors(InterceptorRegistry registry) { ... }
}
  • 关键点
    1. @AutoConfiguration:声明为自动配置类。
    2. @ConditionalOnWebApplication:仅在Servlet环境生效。
    3. @Bean:将CorsFilter注册为Bean。
    4. 实现WebMvcConfigurer:通过继承接口直接扩展Spring MVC配置。
5.2 全局异常处理器示例
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ResponseEntity<String> handleGlobalException(Exception e) { ... }
}
  • 关键点
    • @RestControllerAdvice:标记为全局异常处理类。
    • 无需@Bean,因为Spring通过组件扫描自动识别。

6. 常见问题与解答

Q1:为什么我的自动配置类未被加载?
  • 可能原因
    1. 未在AutoConfiguration.imports文件中声明类。
    2. 依赖未正确引入(如模块B未依赖模块A)。
    3. 条件注解未满足(如@ConditionalOnClass的类不存在)。
  • 解决方案
    • 检查AutoConfiguration.imports文件路径是否正确。
    • 确保模块B的POM中包含模块A的依赖。
    • 在启动日志中搜索Positive matches,确认条件是否满足。
Q2:@Bean和@Component的区别?
注解作用范围使用场景
@Bean方法级在配置类中定义Bean的创建逻辑
@Component类级通过组件扫描自动注册Bean
Q3:为什么自动配置类需要实现WebMvcConfigurer?
  • 原因
    Spring MVC的扩展机制允许通过实现WebMvcConfigurer接口或使用@Bean注册WebMvcConfigurer来添加拦截器、跨域配置等。
  • 示例
    @Override
    public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor());
    }
    

7. 完整自动配置类代码示例

// 模块A的ResourcesConfig.java
@AutoConfiguration
@ConditionalOnWebApplication(type = Type.SERVLET)
public class ResourcesConfig implements WebMvcConfigurer {@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedOriginPattern("*");config.addAllowedMethod("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}@Beanpublic MyInterceptor myInterceptor() {return new MyInterceptor();}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor()).addPathPatterns("/**");}@Bean@ConditionalOnMissingBeanpublic MyService myService() {return new MyServiceImpl();}
}

8. 关键配置文件说明

8.1 AutoConfiguration.imports文件
# 模块A的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.moduleA.config.ResourcesConfig
  • 作用
    告知Spring Boot哪些类是自动配置类,无需手动注册到spring.factories
8.2 spring.factories(Spring Boot 2.x兼容)
# 模块A的META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.moduleA.config.ResourcesConfig,\
com.example.moduleA.handler.GlobalExceptionHandler
  • 兼容性说明
    Spring Boot 3.x支持同时使用两种方式,但推荐使用@AutoConfiguration

9. 总结:注解选择决策树

是否自动配置
是:AutoConfig
声明配置
否:手动配置
注册方式
方式1:@Import
方式2:@ComponentScan
定义Bean
@Bean注解
需在配置类中定义
其他场景
组件注解
组件扫描加载

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

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

相关文章

WEBSTORM前端 —— 第2章:CSS —— 第4节:盒子模型

目录 1.画盒子 2.Pxcook软件 3.盒子模型——组成 4.盒子模型 ——边框线 5.盒子模型——内外边距 6.盒子模型——尺寸计算 7.清除默认样式 8.盒子模型——元素溢出 9.外边距问题 ①合并现象 ②塌陷问题 10.行内元素——内外边距问题 11.盒子模型——圆角 12.盒子…

Kafka和flume整合

需求1&#xff1a;利用flume监控某目录中新生成的文件&#xff0c;将监控到的变更数据发送给kafka&#xff0c;kafka将收到的数据打印到控制台&#xff1a; 在flume/conf下添加.conf文件&#xff0c; vi flume-kafka.conf # 定义 Agent 组件 a1.sourcesr1 a1.sinksk1 a1.c…

Idea 如何配合 grep console过滤并分析文件

这里写自定义目录标题 [grep console插件]()右击打开文件目录&#xff0c;选择 tail in console 同时可以添加自己的快捷键。 ![新的改变](https://i-blog.csdnimg.cn/direct/03423e27cf6c40c5abd2d53982547b61.png) 随后会在idea的菜单栏中出现tail菜单。这里&#xff0c;接下…

怎样学习Electron

学习 Electron 是一个很好的选择&#xff0c;特别是如果你想构建跨平台的桌面应用程序&#xff0c;并且已经有前端开发经验。以下是一个循序渐进的学习指南&#xff0c;帮助你从零开始掌握 Electron。 1. 基础知识 HTML/CSS/JavaScript 确保你对这些基础技术有扎实的理解&am…

MySQL 大数据量分页查询优化指南

问题分析 当对包含50万条记录的edu_test表进行分页查询时&#xff0c;发现随着分页越深入&#xff0c;查询时间越长&#xff1a; limit 0,10&#xff1a;0.05秒limit 200000,10&#xff1a;0.14秒limit 499000,10&#xff1a;0.21秒 通过EXPLAIN分析发现&#xff0c;limit o…

【仿真】Ubuntu 22.04 安装MuJoCo 3.3.2

官方GIthub下载: https://github.com/google-deepmind/mujoco/releases 官网&#xff1a;MuJoCo — Advanced Physics Simulation 文档&#xff1a;Overview - MuJoCo Documentation 主要参考&#xff1a;Ubuntu 22.04 安装Mujoco 3.22 - RobotStudent的文章 - 知乎 简…

最新字节跳动运维云原生面经分享

继续分享最新的go面经。 今天分享的是组织内部的朋友在字节的go运维工程师岗位的云原生方向的面经&#xff0c;涉及Prometheus、Kubernetes、CI/CD、网络代理、MySQL主从、Redis哨兵、系统调优及基础命令行工具等知识点&#xff0c;问题我都整理在下面了 面经详解 Prometheus …

PyQt6实例_pyqtgraph散点图显示工具_代码分享

目录 描述&#xff1a; 效果&#xff1a; 代码&#xff1a; 返回结果对象 字符型横坐标 通用散点图工具 工具主界面 使用举例 描述&#xff1a; 1 本例结合实际应用场景描述散点图的使用。在财报分析中&#xff0c;需要将数值放在同行业中进行比较&#xff0c;从而判…

纯C协程框架NtyCo

原文是由写的&#xff0c;写的真的很好&#xff0c;原文链接&#xff1a;纯c协程框架NtyCo实现与原理-CSDN博客 1.为什么会有协程&#xff0c;协程解决了什么问题&#xff1f; 网络IO优化 在CS&#xff0c;BS的开发模式下&#xff0c;服务器的吞吐量是一个受关注的参数&#x…

信息系统项目管理师——第10章 项目进度管理 笔记

10项目进度管理 1.规划进度管理&#xff1a;项目章程、项目管理计划&#xff08;开发方法、范围管理计划&#xff09;、事业环境因素、组织过程资产——专家判断、数据分析&#xff08;备选方案分析&#xff09;、会议——进度管理计划 2.定义活动&#xff1a;WBS进一步分解&am…

通过门店销售明细表用SQL得到每月每个门店的销冠和按月的同比环比数据

假设我在Snowflake里有销售表&#xff0c;包含ID主键、门店ID、日期、销售员姓名和销售额&#xff0c;需要统计出每个月所有门店和各门店销售额最高的人&#xff0c;不一定是一个人&#xff0c;以及他所在的门店ID和月总销售额。 统计每个月份下&#xff0c;各门店内销售额最高…

移远通信LG69T赋能零跑B10:高精度定位护航,共赴汽车智联未来

当前&#xff0c;汽车行业正以前所未有的速度迈向智能化时代&#xff0c;组合辅助驾驶技术已然成为车厂突出重围的关键所在。高精度定位技术作为实现车辆精准感知与高效协同的基石&#xff0c;其重要性日益凸显。 作为全球领先的物联网及车联网整体解决方案供应商&#xff0c;移…

jmeter-Beashell获取http请求体json

在JMeter中&#xff0c;使用BeanShell处理器或BeanShell Sampler来获取HTTP请求体中的JSON数据是很常见的需求。这通常用于在测试计划中处理和修改请求体&#xff0c;或者在响应后进行验证。以下是一些步骤和示例代码&#xff0c;帮助你使用BeanShell来获取HTTP请求体中的JSON数…

若干查找算法

一、顺序查找 1.原理 2.代码 #if 0 const int FindBySeq(const vector<int>& ListSeq, const int KeyData) {int retrIdx -1;int size ListSeq.size();for(int i 0; i < size; i) {if (ListSeq.at(i) KeyData){retrIdx i;break;}}return retrIdx; } #else c…

Uniapp(vue):生命周期

目录 一、Vue生命周期二、Uniapp中页面的生命周期三、执行顺序比较一、Vue生命周期 setup():是在beforeCreate和created之前运行的,所以可以用setup代替这两个钩子函数。onBeforeMount():已经完成了模板的编译,但是组件还未挂载到DOM上的函数。onMounted():组件挂载到DOM完…

Prometheus监控

1、docker - prometheusgrafana监控与集成到spring boot 服务_grafana spring boot-CSDN博客 2、【IT运维】普罗米修斯基本介绍及监控平台部署&#xff08;PrometheusGrafana&#xff09;-CSDN博客 3、Prometheus监控SpringBoot-CSDN博客 4、springboot集成普罗米修斯-CSDN博客…

C#进阶学习(十四)反射的概念以及关键类Type

目录 本文末尾有相关类中的总结&#xff0c;如有需要直接跳到最后即可 前置知识&#xff1a; 1、程序集&#xff08;Assembly&#xff09; 2、元数据&#xff08;Metadata&#xff09; 3、中间语言&#xff08;IL, Intermediate Language&#xff09; 中间语言&#xff08;…

Kotlin中的also、apply、invoke用法详解

以下是 Kotlin 中作用域函数(let、run、with、also、apply)和 invoke 操作符的完整总结,结合代码示例和对比说明,帮助您理解它们的用法和区别。 一、作用域函数:简化对象操作 作用域函数用于在对象的上下文中执行代码块,并根据函数的不同返回对象本身或 lambda 的结果。…

Ubuntu实现远程文件传输

目录 安装 FileZillaUbuntu 配套设置实现文件传输 在Ubuntu系统中&#xff0c;实现远程文件传输的方法有多种&#xff0c;常见的包括使用SSH&#xff08;Secure Shell&#xff09;的SCP&#xff08;Secure Copy Protocol&#xff09;命令、SFTP&#xff08;SSH File Transfer P…

TEC制冷片详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 三、程序设计 main文件 jdq.h文件 jdq.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 半导体制冷片&#xff08;又称热电模块&#xff09;&#xff0c;是利用半导体材料的珀耳帖效应制造的一种新型制冷元件…