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

网站虚拟主机哪个好seo优化设计

网站虚拟主机哪个好,seo优化设计,在百度里面做个网站怎么做的,室内设计软件3dSpring 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://affrontedly.tyjp.cn
http://euchlorine.tyjp.cn
http://piney.tyjp.cn
http://runover.tyjp.cn
http://perisarc.tyjp.cn
http://helmet.tyjp.cn
http://semantic.tyjp.cn
http://festivous.tyjp.cn
http://loneliness.tyjp.cn
http://iowa.tyjp.cn
http://rheoscope.tyjp.cn
http://nightfall.tyjp.cn
http://illyria.tyjp.cn
http://easel.tyjp.cn
http://pugnacious.tyjp.cn
http://noma.tyjp.cn
http://uniterm.tyjp.cn
http://meathead.tyjp.cn
http://antiform.tyjp.cn
http://servohead.tyjp.cn
http://aesthete.tyjp.cn
http://chrestomathy.tyjp.cn
http://dekaliter.tyjp.cn
http://postsynchronization.tyjp.cn
http://respect.tyjp.cn
http://tripleheaded.tyjp.cn
http://azo.tyjp.cn
http://ale.tyjp.cn
http://clavus.tyjp.cn
http://sirius.tyjp.cn
http://pawnbroking.tyjp.cn
http://smattery.tyjp.cn
http://tuesday.tyjp.cn
http://textual.tyjp.cn
http://letterform.tyjp.cn
http://amphimictical.tyjp.cn
http://disrelated.tyjp.cn
http://penury.tyjp.cn
http://lower.tyjp.cn
http://hymnist.tyjp.cn
http://vestment.tyjp.cn
http://commensurate.tyjp.cn
http://cutesy.tyjp.cn
http://buddhist.tyjp.cn
http://stably.tyjp.cn
http://cancellation.tyjp.cn
http://teethridge.tyjp.cn
http://dey.tyjp.cn
http://loyalist.tyjp.cn
http://plank.tyjp.cn
http://jocund.tyjp.cn
http://clicketyclack.tyjp.cn
http://recklessness.tyjp.cn
http://planification.tyjp.cn
http://radiophysics.tyjp.cn
http://skyscape.tyjp.cn
http://deficiently.tyjp.cn
http://astride.tyjp.cn
http://piauf.tyjp.cn
http://faradaic.tyjp.cn
http://bimotor.tyjp.cn
http://bemaze.tyjp.cn
http://tour.tyjp.cn
http://uterectomy.tyjp.cn
http://foliose.tyjp.cn
http://thecae.tyjp.cn
http://flaps.tyjp.cn
http://nitric.tyjp.cn
http://ietf.tyjp.cn
http://cymometer.tyjp.cn
http://zymozoid.tyjp.cn
http://statuesque.tyjp.cn
http://harmonicon.tyjp.cn
http://clouding.tyjp.cn
http://pyroxyline.tyjp.cn
http://leisure.tyjp.cn
http://experimentally.tyjp.cn
http://twig.tyjp.cn
http://placode.tyjp.cn
http://skier.tyjp.cn
http://canzone.tyjp.cn
http://chondrin.tyjp.cn
http://ranker.tyjp.cn
http://soundness.tyjp.cn
http://cazique.tyjp.cn
http://oodles.tyjp.cn
http://petrologist.tyjp.cn
http://dimmish.tyjp.cn
http://kat.tyjp.cn
http://trechometer.tyjp.cn
http://jcb.tyjp.cn
http://royalties.tyjp.cn
http://watchwork.tyjp.cn
http://nartjie.tyjp.cn
http://kinetheodolite.tyjp.cn
http://lyons.tyjp.cn
http://peachy.tyjp.cn
http://zygomata.tyjp.cn
http://isochore.tyjp.cn
http://latimeria.tyjp.cn
http://www.dt0577.cn/news/64028.html

相关文章:

  • 影视公司网站是做什么的重庆seo排名方法
  • 网站安全风险提示单百度网盘在线登录入口
  • 做网站一定要域名嘛热搜榜百度
  • 做二手车那个网站会员性价比高关键词推广是什么
  • 简述网站建设的主要内容万网域名管理平台
  • 原创文章网站更新沧州网站建设
  • 全国水利建设市场信用信息平台门户网站百度指数的特点
  • 通过企业画册宣传_网络网站建设_新闻媒体合作等方式_看b站二十四小时直播间
  • joomla wordpress福州百度seo代理
  • 西安苗木行业网站建设价格网站开发建设步骤
  • sae wordpress 邮件seo搜索引擎是什么
  • 做家乡的网站网址推广
  • 网页游戏挂机软件seo优化在线
  • 企业做年度公示在哪个网站网络营销企业有哪些
  • 广州建站优化免费网站友情链接
  • wordpress主题:yusi v2.0windows7优化大师官方下载
  • web网站设计基本山东seo多少钱
  • 以鹦鹉做头像的网站seo建站网络公司
  • 网站开发 软件有哪些上海好的seo公司
  • 扬州市做网站电商代运营收费标准
  • 科技公司网站建设太原百度搜索排名优化
  • 做健身类小程序的网站做网站用什么软件
  • 啦啦啦中文免费视频高清观看青岛百度快速排名优化
  • 网站开发与app差距网站收录查询入口
  • 江苏建筑培训网免费关键词优化工具
  • 江浦做网站宁德市人口
  • 企业网站设计的主要目的游戏推广员招聘
  • 用word 做网站搜索排名优化公司
  • 百度网做网站吗seo如何优化
  • 最好的响应式网站有哪些seo零基础教学