Spring的事件监听机制(一)

发布于:2025-09-07 ⋅ 阅读:(18) ⋅ 点赞:(0)

         先看一段问题代码。如果我们要实现一个主线业务,同时需要做一些支线任务。如果都写在一起,会不太好,我们不希望把主线任务耦合到支线任务里面。

package com.example.springdemo.demos.a17;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * @author zhou
 * @version 1.0
 * @description TODO
 * @date 2025/9/6 21:56
 */
@Configuration
public class TestListener {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestListener.class);
        context.getBean(MyService.class).doBusiness();
        context.close();
    }
    @Component
    static class MyService{
        private static final Logger log = LoggerFactory.getLogger(TestListener.class);
        public void doBusiness(){
            log.debug("主线业务");
            log.debug("发送短信");
            log.debug("发送邮件");
        }
    }
}

        Spring提供了事件监听机制去实现主线任务与支线任务的低耦合。实现思路如下:

1.首先需要提供事件对象

    static class MyEvent extends ApplicationEvent{

        public MyEvent(Object source) {
            super(source);
        }
    }

2.实现Spring提供的事件监听器接口,并指定泛型接口是我们自己写的事件对象。重写里面的方法加上我们自己的逻辑。

    @Component
    static class SmsApplicationListener implements ApplicationListener<MyEvent>{
        private static final Logger log = LoggerFactory.getLogger(SmsApplicationListener.class);
        @Override
        public void onApplicationEvent(MyEvent event) {
            log.debug("发送短信");
        }
    }
    @Component
    static class EmailApplicationListener implements ApplicationListener<MyEvent>{
        private static final Logger log = LoggerFactory.getLogger(EmailApplicationListener.class);
        @Override
        public void onApplicationEvent(MyEvent event) {
            log.debug("发送邮件");
        }
    }

3.改造业务代码

   注入事件发布器发布事件。

    @Component
    static class MyService{
        private static final Logger log = LoggerFactory.getLogger(TestListener.class);
        @Autowired
        private ApplicationEventPublisher publisher;
        public void doBusiness(){
            log.debug("主线业务");
           /* log.debug("发送短信");
            log.debug("发送邮件");*/
            publisher.publishEvent(new MyEvent("MyService.doBusiness()"));
        }
    }

   其中MyEvent 构造函数的参数可以是任何有助于监听器理解"发生了什么"和"需要处理什么"的信息,而不仅仅是方法名。

 

打印结果:

           这里监听器执行支线任务是随机的,而且都是在主线程执行,还有优化空间。


网站公告

今日签到

点亮在社区的每一天
去签到