Spring Boot事件的全面指南:事件类、发布者、监听器、异步、条件

ApplicationEvent介绍

SpringBoot中的ApplicationEvent是一种基于观察者模式实现的事件处理方式,它可以用于在Spring容器内部发布和订阅消息。事件监听与发布的过程如下:

  • 事件类(Event):继承自ApplicationEvent类,用于封装事件数据。从Spring Framework 4.2开始,事件类不需要继承ApplicationEvent类,可以是任意对象。
  • 发布者(Publisher):注入ApplicationEventPublisher对象,使用publishEvent()方法发布事件。
  • 监听器(Listener):实现ApplicationListener接口,重写onApplicationEvent()方法处理事件。监听器可以使用@Component注解注册为一个Bean,也可以使用@EventListener注解标注一个方法作为监听器。

事件监听与发布的运用场景有很多,比如:

  • 在Spring Boot启动时初始化数据或资源,比如加载配置文件、做安全认证等。
  • 在Spring Boot应用中实现异步处理,比如发送邮件、执行定时任务等。
  • 在Spring Boot应用中实现业务逻辑的解耦,比如订单支付成功后通知库存服务、物流服务等。

示例

在更新user对象后,发布一个事件,让一个监听器将user对象保存到redis中。为了实现这个功能,参考以下步骤:

  • 创建一个UserUpdateEvent类,不需要继承自ApplicationEvent类,只需要封装user对象。
  • 创建一个UserUpdatePublisher类,注入ApplicationEventPublisher对象,用于发布UserUpdateEvent。
  • 创建一个UserUpdateListener类,不需要实现ApplicationListener接口,只需要使用@EventListener和@Async注解标注一个方法作为异步监听器。
  • 在需要更新user对象的地方,调用UserUpdatePublisher的publishEvent()方法。

示例代码如下:

// UserUpdateEvent.java public class UserUpdateEvent { private User user; public UserUpdateEvent(User user) { this.user = user; } public User getUser() { return user; } } // UserUpdatePublisher.java @Component public class UserUpdatePublisher { @Autowired private ApplicationEventPublisher applicationEventPublisher; public void publishEvent(User user) { System.out.println("Publishing user update event."); UserUpdateEvent userUpdateEvent = new UserUpdateEvent(user); applicationEventPublisher.publishEvent(userUpdateEvent); } } // UserUpdateListener.java @Component public class UserUpdateListener { @Autowired private RedisTemplate<String, Object> redisTemplate; @EventListener @Async public void onUserUpdate(UserUpdateEvent event) { System.out.println("Listening to user update event."); User user = event.getUser(); // save user object to redis redisTemplate.opsForValue().set(user.getId(), user); } } // SomeService.java @Service public class SomeService { @Autowired private UserRepository userRepository; @Autowired private UserUpdatePublisher userUpdatePublisher; public void updateUser(User user) { // update user object in database userRepository.save(user); // publish user update event userUpdatePublisher.publishEvent(user); } }

注意:使用@Async注解实现异步事件监听时,需要在Spring Boot应用中开启异步支持,即在启动类或配置类上添加@EnableAsync注解。

@EventListener注解SpEL表达式实现条件事件监听

使用SpEL表达式实现条件事件监听的方法是,在@EventListener注解中添加condition属性,指定一个布尔值的SpEL表达式,表示事件监听的条件。例如:

@EventListener(condition = "#event.user.name == '张三'") public void onUserUpdate(UserUpdateEvent event) { // 只有当user对象的name属性为张三时,才会执行这个方法 }

SpEL表达式中可以使用event变量来引用事件对象,也可以使用root变量来引用事件对象或方法参数。例如:

@EventListener(condition = "#root.event.user.age > 18") public void onUserUpdate(UserUpdateEvent event) { // 只有当user对象的age属性大于18时,才会执行这个方法 } @EventListener(condition = "#root.args[0].user.gender == '男'") public void onUserUpdate(UserUpdateEvent event) { // 只有当user对象的gender属性为男时,才会执行这个方法 }

SpEL表达式中还可以使用Spring容器中的Bean或属性。例如:

@EventListener(condition = "@userService.isAdmin(#event.user)") public void onUserUpdate(UserUpdateEvent event) { // 只有当userService Bean的isAdmin方法返回true时,才会执行这个方法 } @EventListener(condition = "#event.user.score >= ${user.minScore}") public void onUserUpdate(UserUpdateEvent event) { // 只有当user对象的score属性大于等于配置文件中的user.minScore属性时,才会执行这个方法 }

总结

以上主要涉及了几个方面:

  • Spring Boot中的ApplicationEvent是一种基于观察者模式实现的事件处理方式,它可以用于在Spring容器内部发布和订阅消息,实现业务逻辑的解耦和异步处理。
  • 事件监听与发布的过程涉及到三个角色:事件类、发布者和监听器。事件类用于封装事件数据,发布者用于发布事件,监听器用于处理事件。
  • 事件类可以继承自ApplicationEvent类,也可以是任意对象。从Spring Framework 4.2开始,Spring支持使用任意对象作为事件类,不再强制要求事件类必须继承自ApplicationEvent类。
  • 监听器可以实现ApplicationListener接口,也可以使用@EventListener注解标注一个方法。使用@EventListener注解可以简化监听器的编写,不需要实现接口或注册Bean。
  • 监听器可以使用@Async注解实现异步事件监听,这样可以提高性能和响应速度。使用@Async注解实现异步事件监听时,需要在Spring Boot应用中开启异步支持,即在启动类或配置类上添加@EnableAsync注解。
  • 监听器可以使用@EventListener注解中的condition属性指定一个SpEL表达式,表示事件监听的条件。SpEL表达式中可以使用event变量或root变量引用事件对象或方法参数,也可以使用Spring容器中的Bean或属性。

__EOF__

本文作者菜菜
本文链接https://www.cnblogs.com/caicz/p/17301782.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   菜菜聊架构  阅读(3374)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示