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

做汽车价格的网站建设seo白帽优化

做汽车价格的网站建设,seo白帽优化,广州网站建设的价格,太仓有做网站的地方吗Spring Boot 监听器(Listeners)详细教程 目录 Spring Boot 监听器概述监听器核心概念最佳使用场景实现步骤高级配置详细使用场景总结 1. Spring Boot 监听器概述 Spring Boot 监听器(Listeners)基于 Spring Framework 的事件机制…

Spring Boot 监听器(Listeners)详细教程


目录

  1. Spring Boot 监听器概述
  2. 监听器核心概念
  3. 最佳使用场景
  4. 实现步骤
  5. 高级配置
  6. 详细使用场景
  7. 总结

1. Spring Boot 监听器概述

Spring Boot 监听器(Listeners)基于 Spring Framework 的事件机制(ApplicationEventApplicationListener),用于在应用生命周期或自定义事件触发时执行特定逻辑。它们提供了一种松耦合的方式响应应用状态变化,常用于初始化资源、监控应用状态、执行异步任务等。

2. 核心概念

2.1 事件类型

  • 内置系统事件
    • ContextRefreshedEvent:ApplicationContext初始化或刷新时触发
    • ContextStartedEvent:ApplicationContext启动后触发
    • ContextStoppedEvent:ApplicationContext停止后触发
    • ContextClosedEvent:ApplicationContext关闭后触发
    • ApplicationStartedEvent:Spring Boot应用启动后触发
    • ApplicationReadyEvent:应用准备就绪时触发(推荐在此执行启动逻辑)
    • ApplicationFailedEvent:启动失败时触发
  • 自定义事件:继承ApplicationEvent创建特定业务事件

2.2 监听器类型

  • 接口实现:实现ApplicationListener<EventType>
  • 注解驱动:使用@EventListener注解方法
  • SmartApplicationListener:支持事件类型过滤和顺序控制

简单说就是:

  • 事件(Event):继承 ApplicationEvent 的类,表示一个事件(如应用启动、关闭等)。
  • 监听器(Listener):实现 ApplicationListener 接口或使用 @EventListener 注解的组件,用于响应事件。
  • 事件发布(Publisher):通过 ApplicationEventPublisher 发布事件。

3. 最佳使用场景

场景说明
应用生命周期管理在应用启动、关闭时初始化或释放资源(如数据库连接、线程池)。
异步任务触发通过事件驱动异步处理(如发送邮件、记录日志)。
业务逻辑解耦模块间通过事件通信,避免直接依赖。业务事件处理(订单创建通知、日志审计)
监控与统计监听请求事件统计 API 调用次数、响应时间等。

4. 实现步骤(代码示例)

4.1 系统事件监听

方式1:实现ApplicationListener接口
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;public class SystemStartupListener implements ApplicationListener<ApplicationReadyEvent> {@Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {System.out.println("=== 应用启动完成,执行初始化操作 ===");// 初始化业务数据...}
}
方式2:使用@EventListener注解
import org.springframework.context.event.EventListener;
import org.springframework.boot.context.event.ApplicationStartedEvent;@Component
public class AnnotationBasedListener {@EventListenerpublic void handleStartedEvent(ApplicationStartedEvent event) {System.out.println("=== 应用启动事件捕获 ===");}
}

4.2 自定义事件

步骤1:定义事件类
public class OrderCreateEvent extends ApplicationEvent {private String orderId;public OrderCreateEvent(Object source, String orderId) {super(source);this.orderId = orderId;}public String getOrderId() {return orderId;}
}
步骤2:发布事件
@Service
public class OrderService {@Autowiredprivate ApplicationEventPublisher eventPublisher;public void createOrder(Order order) {// 创建订单逻辑...eventPublisher.publishEvent(new OrderCreateEvent(this, order.getId()));}
}
步骤3:监听事件
@Component
public class OrderEventListener {@EventListenerpublic void handleOrderEvent(OrderCreateEvent event) {System.out.println("收到订单创建事件,订单ID:" + event.getOrderId());// 发送通知、更新统计...}
}

5. 高级配置

5.1 监听器顺序控制

@EventListener
@Order(Ordered.HIGHEST_PRECEDENCE) // 最高优先级
public void handleEventFirst(MyEvent event) {// 最先执行
}

5.2 异步事件处理

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.initialize();return executor;}
}@EventListener
@Async
public void asyncHandleEvent(MyEvent event) {// 异步执行
}

5.3 条件过滤

@EventListener(condition = "#event.orderId.startsWith('VIP')")
public void handleVipOrder(OrderCreateEvent event) {// 只处理VIP订单
}

6.详细使用场景


场景1:应用启动时缓存预热(系统事件监听)

需求描述
在应用启动完成后,自动加载热门商品数据到Redis缓存,提升接口响应速度。

@Component
public class CacheWarmUpListener {private final ProductService productService;private final RedisTemplate<String, Product> redisTemplate;@Autowiredpublic CacheWarmUpListener(ProductService productService, RedisTemplate<String, Product> redisTemplate) {this.productService = productService;this.redisTemplate = redisTemplate;}@EventListener(ApplicationReadyEvent.class)public void warmUpCache() {List<Product> hotProducts = productService.getTop100HotProducts();hotProducts.forEach(product -> redisTemplate.opsForValue().set("product:" + product.getId(), product));System.out.println("=== 已预热" + hotProducts.size() + "条商品数据到Redis ===");}
}

关键点说明

  • 使用ApplicationReadyEvent而非ApplicationStartedEvent,确保数据库连接等基础设施已就绪
  • 通过构造函数注入依赖,避免字段注入的循环依赖问题
  • 预热数据量较大时建议采用分页异步加载

场景2:订单创建后发送多平台通知(自定义事件)

需求描述
当订单创建成功后,需要同时发送短信通知用户、邮件通知客服、更新ERP系统库存。

步骤1:定义自定义事件
public class OrderCreatedEvent extends ApplicationEvent {private final Order order;public OrderCreatedEvent(Object source, Order order) {super(source);this.order = order;}public Order getOrder() {return order;}
}
步骤2:在Service中发布事件
@Service
public class OrderService {private final ApplicationEventPublisher eventPublisher;@Autowiredpublic OrderService(ApplicationEventPublisher eventPublisher) {this.eventPublisher = eventPublisher;}@Transactionalpublic Order createOrder(OrderCreateRequest request) {Order newOrder = // 创建订单的数据库操作...eventPublisher.publishEvent(new OrderCreatedEvent(this, newOrder));return newOrder;}
}
步骤3:多监听器处理事件
@Component
public class OrderNotificationListener {// 短信通知(最高优先级)@EventListener@Order(Ordered.HIGHEST_PRECEDENCE)public void sendSms(OrderCreatedEvent event) {Order order = event.getOrder();SmsService.send(order.getUserPhone(), "您的订单#" + order.getId() + "已创建,金额:" + order.getAmount());}// 邮件通知(异步处理)@Async@EventListenerpublic void sendEmail(OrderCreatedEvent event) {Order order = event.getOrder();EmailTemplate template = EmailTemplate.buildOrderConfirm(order);EmailService.send(template);}// ERP系统库存更新(条件过滤)@EventListener(condition = "#event.order.items.?[isPhysicalProduct].size() > 0")public void updateErpInventory(OrderCreatedEvent event) {ERPInventoryService.updateStock(event.getOrder().getItems());}
}

配置异步支持

@Configuration
@EnableAsync
public class AsyncConfig {@Bean(name = "notificationTaskExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(100);executor.setThreadNamePrefix("Notification-");executor.initialize();return executor;}
}

优势

  • 解耦核心业务与通知逻辑
  • 通过@Order控制短信优先于邮件发送
  • 使用@Async避免邮件发送阻塞主线程
  • 条件表达式跳过虚拟商品库存更新

场景3:全局请求耗时统计(ServletRequestListener)

需求描述
统计所有API请求的处理时间,识别慢接口。

@Component
public class RequestMetricsListener implements ServletRequestListener {private static final ThreadLocal<Long> startTimeHolder = new ThreadLocal<>();@Overridepublic void requestInitialized(ServletRequestEvent sre) {startTimeHolder.set(System.currentTimeMillis());}@Overridepublic void requestDestroyed(ServletRequestEvent sre) {long startTime = startTimeHolder.get();long duration = System.currentTimeMillis() - startTime;HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();String endpoint = request.getRequestURI();String method = request.getMethod();MetricsService.recordRequestMetrics(endpoint, method, duration);// 慢请求预警if(duration > 3000) {AlarmService.notifySlowRequest(endpoint, method, duration);}startTimeHolder.remove();}
}

注册监听器

@Bean
public ServletListenerRegistrationBean<RequestMetricsListener> metricsListener() {return new ServletListenerRegistrationBean<>(new RequestMetricsListener());
}

统计结果示例

GET /api/products 平均耗时 45ms | 95分位 120ms
POST /api/orders 平均耗时 250ms | 最大耗时 3200ms(需优化)

场景4:应用优雅停机(ContextClosedEvent)

需求描述
在应用关闭时,确保完成:1)停止接收新请求 2)等待进行中的任务完成 3)释放资源。

@Component
public class GracefulShutdownListener implements ApplicationListener<ContextClosedEvent> {private final ThreadPoolTaskExecutor taskExecutor;private final DataSource dataSource;@Autowiredpublic GracefulShutdownListener(ThreadPoolTaskExecutor taskExecutor, DataSource dataSource) {this.taskExecutor = taskExecutor;this.dataSource = dataSource;}@Overridepublic void onApplicationEvent(ContextClosedEvent event) {// 1. 关闭线程池shutdownExecutor(taskExecutor);// 2. 关闭数据库连接池if(dataSource instanceof HikariDataSource) {((HikariDataSource) dataSource).close();}// 3. 其他清理工作...System.out.println("=== 资源释放完成,应用安全退出 ===");}private void shutdownExecutor(ExecutorService executor) {executor.shutdown();try {if(!executor.awaitTermination(30, TimeUnit.SECONDS)) {executor.shutdownNow();}} catch (InterruptedException e) {executor.shutdownNow();Thread.currentThread().interrupt();}}
}

停机流程

  1. 收到SIGTERM信号
  2. 关闭新请求入口
  3. 等待30秒处理进行中请求
  4. 强制关闭剩余任务
  5. 释放数据库连接池
  6. 应用退出

场景5:分布式锁异常恢复

需求描述
当获取Redis分布式锁失败时,触发重试机制并记录竞争情况。

自定义事件
public class LockAcquireFailedEvent extends ApplicationEvent {private final String lockKey;private final int retryCount;public LockAcquireFailedEvent(Object source, String lockKey, int retryCount) {super(source);this.lockKey = lockKey;this.retryCount = retryCount;}// getters...
}
事件发布
public class DistributedLock {private final ApplicationEventPublisher eventPublisher;public boolean tryLock(String key, int maxRetries) {int attempts = 0;while(attempts < maxRetries) {if(RedisClient.acquireLock(key)) {return true;}attempts++;eventPublisher.publishEvent(new LockAcquireFailedEvent(this, key, attempts));Thread.sleep(100 * attempts);}return false;}
}
监听处理
@Component
public class LockFailureHandler {private static final Map<String, AtomicInteger> LOCK_CONTENTION = new ConcurrentHashMap<>();@EventListenerpublic void handleLockFailure(LockAcquireFailedEvent event) {String lockKey = event.getLockKey();LOCK_CONTENTION.computeIfAbsent(lockKey, k -> new AtomicInteger(0)).incrementAndGet();// 竞争激烈时动态调整策略if(event.getRetryCount() > 3) {adjustBackoffStrategy(lockKey);}}@Scheduled(fixedRate = 10_000)public void reportContention() {LOCK_CONTENTION.forEach((key, count) -> MetricsService.recordLockContention(key, count.get()));}private void adjustBackoffStrategy(String key) {// 动态增加等待时间或告警}
}

监控面板显示

订单库存锁竞争次数:142次/分钟 → 建议拆分锁粒度
优惠券发放锁竞争:23次/分钟 → 正常范围

最佳实践总结

  1. 事件选择原则

    • 系统生命周期:优先使用ApplicationReadyEvent而非ContextRefreshedEvent
    • 业务事件:根据领域模型设计细粒度事件
  2. 性能优化

    • 耗时操作使用@Async+线程池
    • 高频事件考虑批量处理
  3. 错误处理

    @EventListener
    public void handleEvent(MyEvent event) {try {// 业务逻辑} catch (Exception e) {ErrorTracker.track(e);// 决定是否重新抛出}
    }
    
  4. 测试策略

    @SpringBootTest
    class OrderEventTest {@Autowiredprivate ApplicationEventPublisher publisher;@Testvoid testOrderNotification() {Order mockOrder = createTestOrder();publisher.publishEvent(new OrderCreatedEvent(this, mockOrder));// 验证短信、邮件发送记录}
    }
    

7.总结

通过以上场景可以看出,Spring Boot监听器能优雅地实现:

  • 系统层的资源生命周期管理
  • 业务层的事件驱动架构
  • 运维层的监控预警机制
  • 架构层的解耦与扩展

实际开发中应根据业务复杂度选择合适的事件策略,平衡灵活性与维护成本。

http://www.hkea.cn/news/335685/

相关文章:

  • 网站改版需要多久网站设计与制作毕业论文范文
  • 深圳横岗网站建设网站建设的推广渠道
  • 有没有什么网站免费做名片2023年新闻小学生摘抄
  • 新网金商网站外链查询工具
  • 网站建设的进度竞价托管选择微竞价
  • 网站快速网站推广怎么做一个公司网站
  • 旅游网站模板htmlseo品牌优化整站优化
  • 方圆网站建设aso优化重要吗
  • 做购实惠网站的意义好用的搜索引擎有哪些
  • 怎么把自己笔记本做服务器做个网站搭建网站基本步骤
  • jeecms做企业网站成都网站建设公司排名
  • 沈阳招聘网站开发地推项目平台
  • 798艺术区成都seo达人
  • 平度网站建设抖音代运营收费详细价格
  • 株洲网站优化找哪家seo优化的价格
  • 找印度人做网站sem竞价推广公司
  • 山西网站推广公司网站关键词优化怎么弄
  • 微信分销是什么重庆优化seo
  • 武汉企业网站推广方案永久免费无代码开发平台网站
  • 网站开发岗位群怎样推广产品
  • 桐城市美丽乡村建设专题网站石家庄整站优化技术
  • 北京建网站的公司哪个比较好郑州seo价格
  • 进空间的网站网络营销常见的工具
  • wordpress发文章的id怎么不连续如何做好搜索引擎优化工作
  • 交互式网站如何做seo推广软件排名
  • 西部建设网站惠州seo排名优化
  • 做环球资源网站有没有效果2024百度下载
  • 织梦 安装网站网站搭建需要多少钱
  • 做网站购买备案域名性价比高seo的排名优化
  • 潍坊中脉网站建设公司淄博seo公司