Spring Boot 事件机制 Event 入门

  • Post author:
  • Post category:其他




Spring 事件机制

JDK 也内置了事件机制的实现,考虑到通用性,Spring 的事件机制是基于它之上进行拓展。因此,ApplicationEvent 继承自 java.util.EventObject,ApplicationListener 继承自 java.util.EventListener。

Spring 基于观察者模式,实现了自身的事件机制,由三部分组成:

  1. 事件

    ApplicationEvent

    :通过继承它,实现自定义事件。另外,通过它的 source 属性可以获取事件源,timestamp 属性可以获得发生时间。
  2. 事件发布者

    ApplicationEventPublisher

    :通过它,可以进行事件的发布。
  3. 事件监听器

    ApplicationListener

    :通过实现它,进行指定类型的事件的监听。



入门示例

在这里插入图片描述



引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>boot-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>boot-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <!-- 使用新版阿里云Maven中央仓库,如下是官网-->
            <!-- https://developer.aliyun.com/mvn/guide -->
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

</project>



PointEvent

package com.example.bootdemo.event;

import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;

@Getter
@Setter
public class PointEvent extends ApplicationEvent {

    private String userName;

    private Integer point;

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

    public PointEvent(Object source, String userName, Integer point) {
        super(source);
        this.userName = userName;
        this.point = point;
    }

}



PointEventPublisher

package com.example.bootdemo.event.pulish;

import com.example.bootdemo.event.PointEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class PointEventPublisher implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public void sendPointEvent(String userName, Integer point) {
        PointEvent pointEvent = new PointEvent(this, userName, point);
        applicationEventPublisher.publishEvent(pointEvent);
    }

}



PointEventListener

package com.example.bootdemo.event.listener;

import com.example.bootdemo.event.PointEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class PointEventListener implements ApplicationListener<PointEvent> {

    @Override
    public void onApplicationEvent(PointEvent event) {
        log.info("给用户:{},增加积分:{}", event.getUserName(), event.getPoint());
    }

}



UserController

package com.example.bootdemo.controller;

import com.example.bootdemo.event.pulish.PointEventPublisher;
import com.example.bootdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private PointEventPublisher pointEventPublisher;

    @GetMapping("point")
    public void register(String userName, Integer point) {
        pointEventPublisher.sendPointEvent(userName, point);
    }

}



Spring 内置事件

在 Spring 框架中,自定义了非常多的自定义事件



ApplicationContextEvent

ApplicationContextEvent 是 Spring Context(可以简单理解成 IoC 容器) 相关的事件基类。在 Spring Context 的整个生命周期中,会发布相应的 ApplicationContextEvent 事件。

  1. ContextStartedEvent:Spring Context 启动完成事件。
  2. ContextStoppedEvent:Spring Context 停止完成事件。
  3. ContextClosedEvent:Spring Context 停止开始事件。
  4. ContextRefreshedEvent:Spring Context 初始化或刷新完成事件。



SpringApplicationEvent

SpringApplicationEvent 是 Spring Boot Application(应用)相关的事件基类。在 Application 的整个生命周期中,会发布相应的 SpringApplicationEvent 事件

  1. ApplicationStartingEvent:Application 启动开始事件。
  2. ApplicationEnvironmentPreparedEvent:Spring Environment 准备完成的事件。
  3. ApplicationContextInitializedEvent:Spring Context 准备完成,但是 Bean Definition 未加载时的事件
  4. ApplicationPreparedEvent:Spring Context 准备完成,但是未刷新时的事件。
  5. ApplicationReadyEvent:Application 启动成功事件。
  6. ApplicationFailedEvent:Application 启动失败事件。



参考


芋道 Spring Boot 事件机制 Event 入门



版权声明:本文为CHENFU_ZKK原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。