一、Spring Event-Driven architure

Spring 事件机制 是观察者模式的一种实现(这里需要一个观察者模式文章链接跳转)。Spring 事件在中间加了 一个 EventMultiCaster 作为中间者,用来管理,事件的接收和传递。

spring 实现事件监听自定义:需要继承 ApplicationEvent 和 实现 ApplicationListener 其本质,也是 EventObject 和 EventListener

01.png

二、模拟Spring 事件监听

定义一个任务事件和一个任务事件监听器

  • 任务事件 TaskEvent.java

    1. /**
    2. * <p>任务事件</p>
    3. */
    4. public class TaskEvent extends ApplicationEvent {
    5. public TaskEvent(Object source) {
    6. super(source);
    7. }
    8. }
  • 事件监听 TaskListener.java

    1. /**
    2. * <p>任务事件监听器</p>
    3. */
    4. public class TaskListener implements ApplicationListener<TaskEvent> {
    5. @Override
    6. public void onApplicationEvent(TaskEvent taskEvent) {
    7. System.out.println(" 获取到数据源:" + taskEvent.getSource());
    8. }
    9. }
  • 测试 Event.java

    1. public class EventTest {
    2. public static void main(String[] args) throws Exception{
    3. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    4. // 事件监听
    5. context.addApplicationListener(new TaskListener());
    6. // 启动 IOC容器
    7. context.refresh();
    8. context.publishEvent(new TaskEvent("任务事件"));
    9. System.in.read();
    10. }
    11. }
  • 测试结果

    1. 获取到数据源:任务事件

三、Web开发模拟事件监听机制

准备环境

和上面 的 事件 TaskEvent.java 和 事件监听 TaskListener.java 一致

方式一

启动类注册 任务监听事件

  1. @SpringBootApplication
  2. public class Application {
  3. public static void main(String[] args) {
  4. SpringApplication springApplication = new SpringApplication();
  5. ConfigurableApplicationContext run = springApplication.run(Application.class, args);
  6. run.addApplicationListener(new TaskListener());
  7. }
  8. }

方式二

在配置文件(application.properties)中添加

  1. context.listener.classes=com.qguofeng.webdemo.TaskListener

方式三

直接在 Listener 头上加 @Component

  1. /**
  2. * <p>任务事件监听器</p>
  3. */
  4. @Component
  5. public class TaskListener implements ApplicationListener<TaskEvent> {
  6. @Override
  7. public void onApplicationEvent(TaskEvent taskEvent) {
  8. System.out.println(" 获取到数据源:" + taskEvent.getSource());
  9. }
  10. }

测试控制器

  1. @RestController
  2. public class TaskController {
  3. @RequestMapping("/event/demo")
  4. public String eventWebDemo(){
  5. ListenerPush_1.push(new TaskEvent("任务事件发送"));
  6. return "发送成功";
  7. }
  8. @RequestMapping("/event/demo2")
  9. public String eventWebDemo2(){
  10. ListenerPush_2.push(new TaskEvent("任务事件发送"));
  11. return "发送成功";
  12. }
  13. }

两种消息发送

  • 方式一:ListenerPush_1

    1. /**
    2. * 事件发送工具 1
    3. */
    4. @Component
    5. public class ListenerPush_1 implements ApplicationContextAware {
    6. private static ApplicationContext context;
    7. @Override
    8. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    9. ListenerPush_1.context = applicationContext;
    10. }
    11. public static void push(ApplicationEvent event) {
    12. context.publishEvent(event);
    13. }
    14. }
  • 方式二:ListenerPush_2

    1. @Component
    2. public class ListenerPush_2 implements ApplicationEventPublisherAware {
    3. private static ApplicationEventPublisher applicationEventPublisher;
    4. @Override
    5. public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
    6. this.applicationEventPublisher = applicationEventPublisher;
    7. }
    8. public static void push(ApplicationEvent event){
    9. applicationEventPublisher.publishEvent(event);
    10. }
    11. }

其本质时一样的,都是通过 ApplicationEventPublisher 来进行事件发送

四、总结

使用 方式三在生产环境中,因为 @Component 的使用,也方便 @Autowired 进行 注入,实现复杂功能更方便