Spring Boot事件机制详解
Spring Boot事件机制详解
1. 事件机制基础
1.1 什么是事件驱动架构
事件驱动架构(Event-Driven Architecture, EDA)是一种软件设计模式,其中系统组件通过事件的发布与订阅进行通信。在Spring Boot中,事件机制为应用程序提供了松耦合的组件间通信方式,使得发布者无需关心谁在监听,监听者也无需了解事件来源。
这种设计类似于现实生活中的"广播通知":
- 广播站(事件发布者)发布新闻
- 听众(事件监听者)根据自己的兴趣选择接收信息
- 广播站与听众之间不存在直接依赖关系
1.2 Spring事件机制核心组件
| 组件 | 描述 | 主要职责 |
|---|---|---|
| 事件(Event) | 封装状态变化的消息载体 | 定义事件属性、携带上下文信息 |
| 发布者(Publisher) | 事件的触发方 | 创建事件对象并发布到事件总线 |
| 监听者(Listener) | 事件的处理方 | 注册感兴趣的事件并实现处理逻辑 |
| 事件总线(Event Bus) | 事件传播的通道 | 管理事件的分发与监听者调用 |
1.3 Spring内置事件概览
Spring框架自身定义了多种内置事件,用于标识应用生命周期中的关键节点:
- ContextRefreshedEvent: 当ApplicationContext初始化或刷新完成时触发
- ContextStartedEvent: 当ApplicationContext启动时触发(显式调用start()方法)
- ContextStoppedEvent: 当ApplicationContext停止时触发(显式调用stop()方法)
- ContextClosedEvent: 当ApplicationContext关闭时触发
- RequestHandledEvent: 在Web应用中,当HTTP请求处理完成时触发
Spring Boot在此基础上扩展了更多事件:
- ApplicationStartingEvent: 应用启动开始,除注册监听器和初始化器外,未进行任何处理
- ApplicationEnvironmentPreparedEvent: 环境准备完成,但上下文创建之前
- ApplicationContextInitializedEvent: 上下文已创建并准备就绪,但源未加载
- ApplicationPreparedEvent: 配置和Bean定义加载完成,但上下文未刷新
- ApplicationStartedEvent: 上下文刷新完成,应用启动但未接收命令行或Web请求
- ApplicationReadyEvent: 应用已准备就绪,可以接收请求
- ApplicationFailedEvent: 启动异常时触发
2. 自定义事件实现
2.1 基础实现方式
2.1.1 定义事件
// 方式一:继承ApplicationEvent(传统方式)
public class UserCreatedEvent extends ApplicationEvent {private final String username;public UserCreatedEvent(Object source, String username) {super(source);this.username = username;}public String getUsername() {return username;}
}// 方式二:POJO事件(Spring 4.2+推荐方式)
public class ProductCreatedEvent {private final String productId;private final LocalDateTime createdTime;public ProductCreatedEvent(String productId) {this.productId = productId;this.createdTime = LocalDateTime.now();}// getter方法
}
2.1.2 创建监听器
// 方式一:实现ApplicationListener接口
@Component
public class UserEventListener implements ApplicationListener<UserCreatedEvent> {private static final Logger logger = LoggerFactory.getLogger(UserEventListener.class);@Overridepublic void onApplicationEvent(UserCreatedEvent event) {logger.info("用户创建事件被监听到,用户名: {}", event.getUsername());// 执行业务逻辑}
}// 方式二:使用@EventListener注解(Spring 4.2+推荐方式)
@Component
public class ProductEventListener {private static final Logger logger = LoggerFactory.getLogger(ProductEventListener.class);@EventListenerpublic void handleProductCreated(ProductCreatedEvent event) {logger.info("产品创建事件被监听到,产品ID: {}", event.getProductId());// 执行业务逻辑}
}
2.1.3 发布事件
@Service
public class UserService {private final ApplicationEventPublisher eventPublisher;// 通过构造函数注入ApplicationEventPublisherpublic UserService(ApplicationEventPublisher eventPublisher) {this.eventPublisher = eventPublisher;}public void createUser(String username) {// 业务逻辑logger.info("创建用户: {}", username);// 发布事件eventPublisher.publishEvent(new UserCreatedEvent(this, username));}
}@Service
public class ProductService {private final ApplicationEventPublisher eventPublisher;public ProductService(ApplicationEventPublisher eventPublisher) {this.eventPublisher = eventPublisher;}public void createProduct(String productId) {// 业务逻辑logger.info("创建产品: {}", productId);// 发布POJO事件eventPublisher.publishEvent(new ProductCreatedEvent(productId));}
}
2.2 高级特性
2.2.1 条件事件监听
Spring允许在事件监听器上添加条件,仅当条件满足时才触发监听器:
@Component
public class ConditionalEventListener {@EventListener(condition = "#event.productId.startsWith('PREMIUM')")public void handlePremiumProductOnly(ProductCreatedEvent event) {// 仅处理高级产品}@EventListener(condition = "#{systemProperties['env'] == 'PRODUCTION'}")public void handleInProductionOnly(UserCreatedEvent event) {// 仅在生产环境处理}
}
2.2.2 事件监听顺序控制
当多个监听器订阅同一事件时,可使用@Order注解控制执行顺序:
@Component
public class OrderedEventListeners {@EventListener@Order(1) // 最高优先级public void handleWithHighestPriority(UserCreatedEvent event) {// 先执行此方法}@EventListener@Order(5) // 中等优先级public void handleWithMediumPriority(UserCreatedEvent event) {// 然后执行此方法}@EventListener@Order(10) // 最低优先级public void handleWithLowestPriority(UserCreatedEvent event) {// 最后执行此方法}
}
2.2.3 事件监听返回值作为新事件
事件监听方法可以返回一个对象,此对象将被自动发布为新的事件:
@Component
public class TransactionalEventListener {@EventListenerpublic NotificationEvent handleUserCreated(UserCreatedEvent event) {// 处理用户创建事件// 返回通知事件,将被自动发布return new NotificationEvent("用户 " + event.getUsername() + " 已创建");}@EventListenerpublic List<NotificationEvent> handleProductCreated(ProductCreatedEvent event) {// 可以返回多个事件return Arrays.asList(new NotificationEvent("产品已创建"),new LoggingEvent("产品创建日志记录"));}
}
3. 异步事件处理
3.1 启用异步事件支持
默认情况下,Spring事件处理是同步的,发布者线程会等待所有监听者执行完毕才返回。开启异步支持:
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(25);executor.setThreadNamePrefix("event-async-");executor.initialize();return executor;}@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return new SimpleAsyncUncaughtExceptionHandler();}
}
3.2 异步事件监听器
@Component
public class AsyncEventListener {@Async@EventListenerpublic void handleAsynchronously(UserCreatedEvent event) {// 此方法将在单独的线程中执行logger.info("异步处理用户创建事件,线程: {}", Thread.currentThread().getName());}
}
3.3 同步与异步对比
| 特性 | 同步事件 | 异步事件 |
|---|---|---|
| 执行线程 | 发布者线程 | 线程池中的线程 |
| 执行顺序 | 可预测的顺序 | 不确定的顺序 |
| 事务传播 | 共享发布者事务 | 独立事务上下文 |
| 异常处理 | 异常会传播到发布者 | 异常在线程池中处理 |
| 适用场景 | 关键业务流程 | 非关键后台处理 |
4. 事务事件处理
4.1 事务绑定事件
Spring提供了@TransactionalEventListener注解,允许将事件处理与事务状态绑定:
@Component
public class OrderTransactionalEventListener {@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)public void handleAfterCommit(OrderCreatedEvent event) {// 仅在事务成功提交后执行// 适合发送通知、更新缓存等操作}@TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)public void handleAfterRollback(OrderCreatedEvent event) {// 仅在事务回滚后执行// 适合记录失败信息、发送告警等}@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)public void handleAfterCompletion(OrderCreatedEvent event) {// 在事务完成后执行(无论提交或回滚)// 适合清理资源等操作}@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)public void handleBeforeCommit(OrderCreatedEvent event) {// 在事务提交前执行// 适合最终验证等操作}
}
4.2 事务事件处理失败策略
@TransactionalEventListener提供了fallbackExecution属性,控制无事务环境下的行为:
@Component
public class FallbackEventListener {@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT,fallbackExecution = true // 即使没有事务也会执行)public void handleWithFallback(OrderCreatedEvent event) {// 在事务提交后执行,或在没有事务的情况下也执行}@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT,fallbackExecution = false // 默认值,没有事务则不执行)public void handleWithoutFallback(OrderCreatedEvent event) {// 仅在事务提交后执行,没有事务则不执行}
}
5. 实战应用场景
5.1 系统通知场景
// 事件定义
public class SystemNotificationEvent {private final String title;private final String content;private final NotificationLevel level;// 构造函数和getter方法public enum NotificationLevel {INFO, WARNING, ERROR, CRITICAL}
}// 多渠道通知监听器
@Component
public class NotificationListeners {@EventListener@Order(1)public void logNotification(SystemNotificationEvent event) {// 记录所有通知String logLevel = switch(event.getLevel()) {case INFO -> "INFO";case WARNING -> "WARN";case ERROR, CRITICAL -> "ERROR";};logger.atLevel(Level.valueOf(logLevel)).log("系统通知: {} - {}", event.getTitle(), event.getContent());}@EventListener(condition = "#event.level == T(com.example.SystemNotificationEvent.NotificationLevel).WARNING " +"or #event.level.name() == 'ERROR'")@Order(2)public void emailNotification(SystemNotificationEvent event) {// 发送邮件通知emailService.sendEmail("系统通知: " + event.getTitle(),event.getContent());}@Async@EventListener(condition = "#event.level.name() == 'CRITICAL'")@Order(3)public void smsNotification(SystemNotificationEvent event) {// 发送短信通知smsService.sendSms("紧急系统通知: " + event.getTitle(),event.getContent());}
}
5.2 缓存更新场景
// 事件定义
public class EntityChangedEvent<T> {private final T entity;private final ChangeType changeType;private final Class<T> entityType;// 构造函数和getter方法public enum ChangeType {CREATED, UPDATED, DELETED}
}// 缓存更新监听器
@Component
public class CacheUpdateListener {private final CacheManager cacheManager;public CacheUpdateListener(CacheManager cacheManager) {this.cacheManager = cacheManager;}@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)public void handleProductChange(EntityChangedEvent<Product> event) {String cacheKey = "product:" + event.getEntity().getId();Cache productCache = cacheManager.getCache("products");switch(event.getChangeType()) {case CREATED, UPDATED:productCache.put(cacheKey, event.getEntity());break;case DELETED:productCache.evict(cacheKey);break;}}
}// 在服务中发布事件
@Service
@Transactional
public class ProductService {private final ApplicationEventPublisher eventPublisher;// 构造函数public Product updateProduct(Product product) {// 业务逻辑Product updated = productRepository.save(product);// 发布事件eventPublisher.publishEvent(new EntityChangedEvent<>(updated, EntityChangedEvent.ChangeType.UPDATED, Product.class));return updated;}
}
5.3 审计日志场景
// 定义审计事件
public class AuditEvent {private final String principal;private final String action;private final String resource;private final Map<String, Object> details;private final LocalDateTime timestamp;// 构造函数和getter方法
}// 审计监听器
@Component
public class AuditEventListener {private final AuditRepository auditRepository;// 构造函数@Async@EventListenerpublic void persistAuditLog(AuditEvent event) {AuditLog log = new AuditLog();log.setPrincipal(event.getPrincipal());log.setAction(event.getAction());log.setResource(event.getResource());log.setDetails(objectMapper.writeValueAsString(event.getDetails()));log.setTimestamp(event.getTimestamp());auditRepository.save(log);}
}// 在控制器中使用
@RestController
@RequestMapping("/api/users")
public class UserController {private final UserService userService;private final ApplicationEventPublisher eventPublisher;// 构造函数@PostMappingpublic ResponseEntity<User> createUser(@RequestBody User user, Principal principal) {User created = userService.createUser(user);// 发布审计事件eventPublisher.publishEvent(new AuditEvent(principal.getName(),"CREATE","USER:" + created.getId(),Map.of("username", created.getUsername(), "email", created.getEmail()),LocalDateTime.now()));return ResponseEntity.created(URI.create("/api/users/" + created.getId())).body(created);}
}
6. 最佳实践与优化建议
6.1 设计原则
-
事件粒度控制:
- 事件应该表示"已发生的事实",使用过去时态命名
- 避免过细粒度导致事件爆炸,也避免过粗粒度导致语义不清
-
事件数据包含:
- 包含足够上下文信息,但避免过度包含导致内存压力
- 考虑仅包含ID等引用信息,而非完整对象图
-
监听器职责单一:
- 每个监听器专注处理特定类型的业务逻辑
- 避免在单个监听器中耦合多种不相关的处理逻辑
6.2 性能优化
-
异步处理大批量事件:
- 对非关键路径使用
@Async提高吞吐量 - 为异步事件处理配置专用线程池,避免阻塞其他异步操作
- 对非关键路径使用
-
避免监听器中的阻塞操作:
- 监听器中避免进行远程调用、复杂计算等阻塞操作
- 考虑在监听器中进一步委派任务到专用工作线程
-
批量事件处理:
- 对高频事件,考虑批量收集后一次性处理
- 使用定时任务或缓冲区策略减少处理次数
6.3 异常处理策略
-
同步监听器异常处理:
- 同步监听器中的异常会传播到发布者
- 关键业务流程应在监听器中妥善捕获异常,避免影响主流程
-
异步监听器异常处理:
- 配置全局
AsyncUncaughtExceptionHandler处理未捕获异常 - 在监听器内部使用try-catch块并记录详细日志
- 配置全局
-
事务监听器异常处理:
@TransactionalEventListener的异常不会回滚主事务- phase = BEFORE_COMMIT除外
- 对关键操作,考虑使用补偿机制或重试策略
6.4 测试策略
-
事件发布测试:
- 使用
ApplicationEventPublisherAware接口验证事件发布 - 使用
ArgumentCaptor捕获并验证事件内容
- 使用
-
监听器测试:
- 直接调用监听方法进行单元测试
- 使用Spring Test提供的测试事件发布机制
-
端到端测试:
- 使用
@SpringBootTest进行完整集成测试 - 验证事件监听带来的系统状态变化
- 使用
7. Spring Boot 3.x新特性
7.1 函数式风格事件监听
Spring Boot 3.x增强了对函数式编程风格的支持:
@Configuration
public class FunctionalEventConfig {@Beanpublic ApplicationListener<ProductCreatedEvent> productCreatedListener() {return event -> {// 函数式处理逻辑logger.info("函数式监听器: 产品已创建 - {}", event.getProductId());};}@Beanpublic ApplicationListener<ApplicationReadyEvent> applicationReadyListener() {return event -> {// 应用就绪后的处理逻辑};}
}
7.2 泛型事件处理
Spring Boot 3.x改进了对泛型事件的支持:
// 泛型基础事件
public class EntityEvent<T> {private final T entity;private final String action;// 构造函数和getter
}// 泛型监听器
@Component
public class GenericEntityListener {@EventListenerpublic void handleUserEvent(EntityEvent<User> event) {// 专门处理User实体事件}@EventListenerpublic void handleProductEvent(EntityEvent<Product> event) {// 专门处理Product实体事件}@EventListenerpublic void handleAnyEntityEvent(EntityEvent<?> event) {// 处理任何实体事件}
}
7.3 响应式事件支持
Spring Boot 3.x进一步增强了与Project Reactor的集成:
// 响应式事件发布
@Service
public class ReactiveProductService {private final ApplicationEventPublisher eventPublisher;// 构造函数public Mono<Product> createProduct(Product product) {return productRepository.save(product).doOnSuccess(saved -> {// 发布事件eventPublisher.publishEvent(new ProductCreatedEvent(saved.getId()));});}
}// 与响应式流结合的监听器
@Component
public class ReactiveEventListener {private final ProductSearchRepository searchRepository;// 构造函数@EventListenerpublic void updateSearchIndex(ProductCreatedEvent event) {// 使用响应式API更新搜索索引searchRepository.findById(event.getProductId()).flatMap(product -> searchRepository.index(product)).subscribe(indexed -> logger.info("产品已索引: {}", event.getProductId()),error -> logger.error("索引失败: {}", error.getMessage()));}
}
8. 排错指南
8.1 常见问题与解决方案
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 事件监听器未被调用 | 1. 监听器未注册为Spring Bean 2. 事件类型不匹配 | 1. 确保使用@Component注解 2. 检查事件类型继承关系 |
| 事务事件监听器未执行 | 1. 没有活跃事务 2. 事务传播行为不正确 | 1. 检查@Transactional注解位置 2. 考虑设置fallbackExecution=true |
| 异步事件死锁 | 1. 线程池配置不当 2. 事件监听链过长 | 1. 增加线程池容量 2. 拆分事件处理链路 |
| 事件处理顺序错乱 | 未正确设置@Order注解 | 为监听方法添加明确的@Order值 |
| 内存压力过大 | 1. 事件对象过大 2. 事件发布频率过高 | 1. 减少事件中的数据量 2. 实现批处理机制 |
8.2 调试技巧
-
启用Spring事件DEBUG日志:
logging.level.org.springframework.context.event=DEBUG -
监控事件发布情况:
@Aspect @Component public class EventPublishingAspect {@Around("execution(* org.springframework.context.ApplicationEventPublisher.publishEvent(..))")public Object logEventPublishing(ProceedingJoinPoint pjp) throws Throwable {Object event = pjp.getArgs()[0];logger.debug("发布事件: {}", event);long start = System.currentTimeMillis();try {return pjp.proceed();} finally {logger.debug("事件处理完成: {}, 耗时: {}ms", event, System.currentTimeMillis() - start);}} } -
监控监听器执行情况:
@Aspect @Component public class EventListenerAspect {@Around("@annotation(org.springframework.context.event.EventListener)")public Object logEventListener(ProceedingJoinPoint pjp) throws Throwable {logger.debug("执行监听器: {}.{}", pjp.getTarget().getClass().getSimpleName(),pjp.getSignature().getName());return pjp.proceed();} }
9. 总结
Spring Boot事件机制为应用程序提供了一种强大的解耦通信方式,通过事件驱动架构可以实现组件间的松耦合交互。本文详细介绍了Spring事件的基础概念、实现方式、高级特性以及最佳实践。
主要要点:
- 灵活的事件定义:支持传统ApplicationEvent继承和POJO事件两种方式
- 多样的监听方式:支持接口实现和注解声明两种风格
- 丰富的处理模式:同步、异步、事务绑定等多种处理模式
- 强大的集成能力:与Spring生态深度集成,支持条件处理、顺序控制等
通过合理利用Spring Boot事件机制,可以构建出响应迅速、松耦合、易于扩展的应用程序架构,特别适合于复杂业务场景下的系统设计。
事件驱动架构不仅提升了代码的可维护性,还为系统提供了更好的扩展性和可测试性,是构建现代企业应用的重要设计模式。
相关文章:
Spring Boot事件机制详解
Spring Boot事件机制详解 1. 事件机制基础 1.1 什么是事件驱动架构 事件驱动架构(Event-Driven Architecture, EDA)是一种软件设计模式,其中系统组件通过事件的发布与订阅进行通信。在Spring Boot中,事件机制为应用程序提供了松耦合的组件间通信方式&…...
【商城实战(63)】配送区域与运费设置全解析
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配…...
2025高频面试算法总结篇【字符串】
文章目录 直接刷题链接直达无重复字符的最长子串给定一个数,删除K位得到最小值至多包含 K 个不同字符的最长子串字符串的排列至少有K个重复字符的最长子串 直接刷题链接直达 如何找出一个字符串中的最大不重复子串 3. 无重复字符的最长子串 给定一个数࿰…...
Python散点密度图(Scatter Density Plot):数据可视化的强大工具
在数据驱动决策的时代,能够高效地处理和可视化多变量数据是一项 crucial 的技能。今天,我们就来深入探讨散点密度图(Scatter Density Plot),这是一种将散点图和核密度估计相结合的数据可视化技术,主要用于展示大量数据点在二维平面上的分布情况。 一、散点密度图的特点 …...
Oracle 数据库安全评估(DBSAT)简明过程
下载DBSAT 从这里下载。 实际是从MOS中下载,即:Oracle Database Security Assessment Tool (DBSAT) (Doc ID 2138254.1)。 最新版本为3.1.0 (July 2024),名为dbsat.zip,近45MB。 $ ls -lh dbsat.zip -rw-rw-r-- 1 oracle oins…...
【T2I】Divide Bind Your Attention for Improved Generative Semantic Nursing
CODE: GitHub - boschresearch/Divide-and-Bind: Official implementation of "Divide & Bind Your Attention for Improved Generative Semantic Nursing" (BMVC 2023 Oral) ABSTRACT 新兴的大规模文本到图像生成模型,如稳定扩散(SD),已…...
【2025】基于springboot+uniapp的企业培训打卡小程序设计与实现(源码、万字文档、图文修改、调试答疑)
基于 Spring Boot uniapp 的企业培训打卡小程序设计与实现 系统功能结构图如下: 一、课题背景 在当今快节奏的商业环境中,企业培训对于员工的成长和企业的发展至关重要。为了满足企业对高效培训管理和员工便捷学习的需求,基于 Spring Boot …...
腾讯面经,有点难度~
今天分享组织内的朋友在腾讯安全的实习面经。 内容涵盖了QPS测试方法、SQL聚合查询、Linux进程管理、Redis数据结构与持久化、NAT原理、Docker隔离机制、Go语言GMP调度模型、协程控制、系统调用流程、变量逃逸分析及map操作等等知识点。 下面是我整理的面经详解: …...
LeetCode(704):二分查找
二分查找 题目链接 题目:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 #include<stdio.h> //左闭…...
探索AI的无限可能,体验智能对话的未来,大模型 API 演示
探索AI的无限可能,体验智能对话的未来,大模型 API 演示 效果展示: 项目概述 这是一个基于 Vue 3 TypeScript Vite 构建的 Vista AI 演示项目,旨在提供一个简洁易用的界面来展示 Vista AI 大语言模型的能力。项目包含 API 演示…...
26考研——图_图的存储(6)
408答疑 文章目录 二、图的存储图的存储相关概念邻接矩阵存储方式邻接矩阵的定义顶点的度计算邻接矩阵的特点邻接矩阵的局限性 应用场景邻接矩阵的幂次意义(了解即可) 邻接表存储方式邻接表定义邻接表结构邻接表的特点 邻接矩阵和邻接表的适用性差异十字…...
Spark读取文件系统的数据(sbt打包测试)-入门级别Demo
学习目标 通过本关卡练习,您将学到: 如何使用Spark访问本地文件和HDFS文件Spark应用程序的编写、编译和运行方法 相关知识 操作系统:Ubuntu 16.04; Spark版本:2.4.0; Hadoop版本:3.1.3。 编…...
5.1 位运算专题:LeetCode 面试题 01.01. 判定字符是否唯一
1. 题目链接 LeetCode 面试题 01.01. 判定字符是否唯一 2. 题目描述 实现一个算法,确定一个字符串的所有字符是否全部唯一(即没有重复字符)。要求如下: 不使用额外的数据结构(如哈希表)字符串仅包含小写…...
datawhale组队学习--大语言模型—task4:Transformer架构及详细配置
第五章 模型架构 在前述章节中已经对预训练数据的准备流程(第 4 章)进行了介绍。本章主 要讨论大语言模型的模型架构选择,主要围绕 Transformer 模型(第 5.1 节)、详细 配置(第 5.2 节)、主流架…...
Python虚拟环境:从入门到实战指南
目录 一、为什么需要Python虚拟环境? 二、如何创建Python虚拟环境? 1. 使用venv(Python 3.3内置) 2. 使用virtualenv(第三方工具) 3. 使用conda(适合数据科学项目) 三、虚拟环…...
如何提升 Java 开发能力?
如何提升 Java 开发能力? 要系统提升 Java 开发能力,需从 基础巩固、技术拓展、实战经验、持续学习 四个维度入手。以下是详细的进阶路径和具体建议: 一、夯实 Java 核心基础 深入理解语言特性 必学内容: JVM 原理:…...
《TCP/IP网络编程》学习笔记 | Chapter 21:异步通知 I/O 模型
《TCP/IP网络编程》学习笔记 | Chapter 21:异步通知 I/O 模型 《TCP/IP网络编程》学习笔记 | Chapter 21:异步通知 I/O 模型同步与异步同步异步对比同步 I/O 的缺点异步 I/O 的优点 理解异步通知 I/O 模型实现异步通知 I/O 模型WSAEventSelect 函数和通知…...
Qt6相对Qt5的主要提升(AI总结)
我: Qt 6 相对于5 有哪些新功能? Qt 6 相对于 Qt 5 有诸多新功能和改进,以下是主要的新增特性: 1. 架构和核心库的重构 模块化设计:Qt 6 采用了更加灵活的模块化设计,开发者可以按需引入必要的功能模块&a…...
消息队列ActiveMQ、RabbitMQ、RocketMQ、Kafka对比分析和选型
ActiveMQ、RabbitMQ、RocketMQ、Kafka对比分析和选型 四大消息队列详细对比 1. ActiveMQ 核心特性: 基于JMS规范,支持多种协议(AMQP、STOPP、MQTT等)。提供主从架构(Master-Slave)和共享存储集群。支持持…...
2025:sql注入详细介绍
先说一个阿里云学生无门槛免费领一年2核4g服务器的方法: 阿里云服务器学生无门槛免费领一年2核4g_阿里云学生认证免费服务器-CSDN博客 SQL注入(SQL Injection)是一种常见的网络安全漏洞,攻击者通过在应用程序的输入参数中注入恶意…...
MyBatis操作数据库进阶——动态SQL
动态 SQL 是根据程序运行时的条件灵活生成不同 SQL 语句的技术。它的核心目的是在不修改代码 的前提下,通过条件判断、循环等逻辑,动态拼接 SQL 片段,解决传统 SQL 语句死板、难以应对复杂业务场景的问题。 一、<if> 标签 先来观…...
使用LLama-Factory的简易教程(Llama3微调案例+详细步骤)
引言:一套快速实现 Llama3 中文微调的教程 主要参考:胖虎遛二狗的 B 站教学视频《【大模型微调】使用Llama Factory实现中文llama3微调》 ✅ 笔者简介:Wang Linyong,西工大,2023级,计算机技术 研究方向&am…...
LabVIEW发电平台数据采集系统
本文详细介绍了基于LabVIEW的摇臂式波浪发电平台数据采集系统的设计与实现。通过整合LabVIEW软件与多种传感器技术,本系统能够有效提升数据采集的准确性和效率,为波浪能的利用和发电设备的优化提供科学依据。 项目背景 随着全球能源需求增长和环境保…...
气象可视化卫星云图的方式:方法与架构详解
气象卫星云图是气象预报和气候研究的重要数据来源。通过可视化技术,我们可以将卫星云图数据转化为直观的图像或动画,帮助用户更好地理解气象变化。本文将详细介绍卫星云图可视化的方法、架构和代码实现。 一、卫星云图可视化方法 1. 数据获取与预处理 卫星云图数据通常来源…...
abaqus 二次开发 No module named ‘abaqusConstants
在 Python 中遇到 “No module named ‘abaqusConstants’” 错误通常意味着 Python 无法找到名为 abaqusConstants 的模块。这可能是由以下几个原因造成的: 拼写错误:首先确认模块名是否正确。通常在 Abaqus 的 Python 环境中,正确的模块名…...
【蓝桥杯】每日练习 Day7
目录 前言 领导者 分析 代码 空调 分析 代码 面包店 分析 代码 前言 今天是第一部分的最后一天(主打记忆恢复术和锻炼思维),从明天开始主播会逐步更新从位运算到dp问题的常见题型。 领导者(分类讨论) 分析 …...
贪心算法(11)(java)加油站
题目:在一条环路上有n个加油站,其中第i个加油站有汽油 gas[i]升.。 你有一辆油箱容量无限的的汽车,从第i个加油站开往第i1个加油站需要消耗汽油 cost[i]升。你从其中的一个加油站出发,开始时油箱为空。 给定…...
Python(4)Python函数编程性能优化全指南:从基础语法到并发调优
目录 一、Lambda性能优化原理1.1 内联执行优势1.2 并行计算加速 二、工程级优化策略2.1 内存管理机制2.2 类型提示增强 三、生产环境最佳实践3.1 代码可读性平衡3.2 异常处理模式 四、性能调优案例4.1 排序算法优化4.2 数据管道加速 五、未来演进方向5.1 JIT编译优化5.2 类型系…...
本地部署Stable Diffusion生成爆火的AI图片
直接上代码 Mapping("/send") Post public Object send(Body String promptBody) { JSONObject postSend new JSONObject(); System.out.println(promptBody); JSONObject body JSONObject.parseObject(promptBody); List<S…...
qiankun微前端的使用
qiankun使用时注意以下几个点 1,子应用项目框架(react,vue)使用的打包格式需要为 umd 格式 2,子应用项目最好配置不受同源策略(跨域)的影响 3,子应用最好使用的路由模式是 histor…...
