spring中的applicationEvent和applicationListener使用

本文深入解析Spring框架中的事件监听机制,包括ApplicationEvent和ApplicationListener的使用。通过具体示例,展示了如何创建事件、监听器及发布器,实现系统业务逻辑解耦,提高可扩展性和维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

spring中的applicationEvent和applicationListener使用

ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,设计初衷也是为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性。
事件发布者并不需要考虑谁去监听,监听具体的实现内容是什么,发布者的工作只是为了发布事件而已。
通过 ApplicationEvent 类和 ApplicationListener 接口来提供在 ApplicationContext 中处理事件。如果一个 bean 实现 ApplicationListener,那么每次 ApplicationEvent 被发布到 ApplicationContext 上,那个 bean 会被通知。

Spring 内置事件 & 描述
1ContextRefreshedEvent ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在 ConfigurableApplicationContext 接口中使用 refresh() 方法来发生。
2ContextStartedEvent当使用 ConfigurableApplicationContext 接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。
3ContextStoppedEvent当使用 ConfigurableApplicationContext 接口中的 stop() 方法停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。
4ContextClosedEvent当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。
5RequestHandledEvent这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。

测试思路

添加用户,当用户不存在时,正常添加用户,当用户存在时触发监听器…

创建event事件

继承applicationEvent即可

/**
* 这是创建了一个事件,当使用此事件时,会根据条件触发监听器
*/
@Data
public class UserEvent extends ApplicationEvent {
   private  String name;

   public UserEvent(Object source, String name) {
       super(source);
       this.name = name;
   }
}

创建监听器

使用注解的方式创建,简单灵活.监听器可以创建多个,使用@Order(1)标注执行顺序,使用@Async执行异步的处理(启动类开始异步).

/**
 * 这是一个事件的监听器,当监听到事件的时候回执行方法.
 */
@Component
public class UserAddListener {

    @Async
    @EventListener
    @Order(1)
    public void listener1(UserEvent userEvent) {
        System.out.println(Thread.currentThread().getName()+ userEvent.getName()+"已经存在了1111");
    }

    @Async
    @EventListener
    @Order(2)
    public void listener2(UserEvent userEvent) {
        System.out.println(Thread.currentThread().getName()+ userEvent.getName()+"已经存在了22222");
    }
}

创建发布器

主要的业务逻辑都在这里,这里是我们调用触发监听器方法的地方.

/**
 * 这是一个事件发布器,这里有具体的监听的事件的方法.例如addUser()
 */
@Service
public class UserService  {
    //已经存在的用户名,出现重复则触发listener
    private List<String> userList=new ArrayList<>(Arrays.asList("zs","ls","ww","zl"));

    public void setUserList(List<String> userList) {
        this.userList = userList;
    }

    @Autowired
    private ApplicationContext context;

    public void addUser(String name) {
        UserEvent event = new UserEvent(context, name);
        for (String str : userList) {
        //当用户存在时,触发
            if (str.equals(event.getName())) {
                context.publishEvent(event);
            }
        }
    }
}

简单的测试

@RestController
public class ListenerController {
    @Autowired
    private UserService userService;

    @RequestMapping("/test01")
    public void test01() {
        userService.addUser("qq");
        System.out.println(Thread.currentThread().getName()+"qq在list中不存在,不会触发listener");
    }

    @RequestMapping("/test02")
    public void test02() {
        userService.addUser("zs");
        System.out.println(Thread.currentThread().getName()+"zs在list中已经存在,会触发listener");
    }
}

结果

当触发test01时不会触发监听器,因为qq不存在列表中.
在这里插入图片描述
当触发test02时会触发监听器.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值