Spring Boot 事件机制 Event 入门
Spring 事件机制
JDK 也内置了事件机制的实现,考虑到通用性,Spring 的事件机制是基于它之上进行拓展。因此,ApplicationEvent 继承自 java.util.EventObject,ApplicationListener 继承自 java.util.EventListener。
Spring 基于观察者模式,实现了自身的事件机制,由三部分组成:
-
事件
ApplicationEvent
:通过继承它,实现自定义事件。另外,通过它的 source 属性可以获取事件源,timestamp 属性可以获得发生时间。 -
事件发布者
ApplicationEventPublisher
:通过它,可以进行事件的发布。 -
事件监听器
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 事件。
- ContextStartedEvent:Spring Context 启动完成事件。
- ContextStoppedEvent:Spring Context 停止完成事件。
- ContextClosedEvent:Spring Context 停止开始事件。
- ContextRefreshedEvent:Spring Context 初始化或刷新完成事件。
SpringApplicationEvent
SpringApplicationEvent 是 Spring Boot Application(应用)相关的事件基类。在 Application 的整个生命周期中,会发布相应的 SpringApplicationEvent 事件
- ApplicationStartingEvent:Application 启动开始事件。
- ApplicationEnvironmentPreparedEvent:Spring Environment 准备完成的事件。
- ApplicationContextInitializedEvent:Spring Context 准备完成,但是 Bean Definition 未加载时的事件
- ApplicationPreparedEvent:Spring Context 准备完成,但是未刷新时的事件。
- ApplicationReadyEvent:Application 启动成功事件。
- ApplicationFailedEvent:Application 启动失败事件。
参考
版权声明:本文为CHENFU_ZKK原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。