Spring Boot ApplicationReadyEvent 教程展示了在应用就绪后如何执行任务。
Spring Boot 应用发出各种事件。 我们可以使用侦听器对此类事件做出反应。
例如,ApplicationStartedEvent
是在刷新上下文之后但在调用任何应用和命令行运行程序之前发送的。 在调用任何应用和命令行运行程序之后,将发送ApplicationReadyEvent
。 它指示该应用已准备就绪,可以处理请求。
Spring Boot ApplicationReadyEvent
示例
以下 Spring Boot 应用是一个简单的 Web 应用,可响应ApplicationStartedEvent
触发 Web 请求。 该请求是通过 WebClient 发出的。
pom.xml
src
├───main
│ ├───java
│ │ └───com
│ │ └───zetcode
│ │ │ Application.java
│ │ ├───bean
│ │ │ TimeResponse.java
│ │ ├───event
│ │ │ AppEvents.java
│ │ └───routes
│ │ AppRoutes.java
│ └───resources
└───test
└───java
└───com
└───zetcode
└───routes
AppRoutesTest.java
这是项目结构。
pom.xml
<?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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zetcode</groupId>
<artifactId>applicationreadyevent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
这是 Maven 构建文件。 spring-boot-starter-webflux
是使用 Spring Framework 的 Reactive Web 支持构建 WebFlux 应用的入门。
com/zetcode/bean/TimeResponse.java
package com.zetcode.bean;
public class TimeResponse {
private String date;
private Long unixtime;
private String time;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public Long getUnixtime() {
return unixtime;
}
public void setUnixtime(Long unixtime) {
this.unixtime = unixtime;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("TimeResponse{");
sb.append("date='").append(date).append('\'');
sb.append(", unixtime=").append(unixtime);
sb.append(", time='").append(time).append('\'');
sb.append('}');
return sb.toString();
}
}
这是TimeResponse
bean。 它用于存储来自 Web 请求的数据。
com/zetcode/event/AppEvents.java
package com.zetcode.event;
import com.zetcode.bean.TimeResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Component
public class AppEvents {
private static final Logger logger = LoggerFactory.getLogger(AppEvents.class);
@EventListener(ApplicationReadyEvent.class)
public void startApp() {
var webClient = WebClient.create("http://time.jsontest.com/");
Mono<TimeResponse> result = webClient.get()
.retrieve()
.bodyToMono(TimeResponse.class);
result.subscribe(res -> logger.info("{}", res));
}
}
在AppEvents
中,我们创建了一个简单的 GET 请求。
@EventListener(ApplicationReadyEvent.class)
public void startApp() {
使用@EventListener
注解,我们注册ApplicationReadyEvent
。
var webClient = WebClient.create("http://time.jsontest.com/");
从http://time.jsontest.com/
中,我们可以获得当前时间。
Mono<TimeResponse> result = webClient.get()
.retrieve()
.bodyToMono(TimeResponse.class);
result.subscribe(res -> logger.info("{}", res));
使用WebClient
,我们向站点创建一个 GET 请求,并将结果输出到终端。
com/zetcode/routes/AppRoutes.java
package com.zetcode.routes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
@Configuration
public class AppRoutes {
@Bean
RouterFunction<ServerResponse> home() {
return route(GET("/"), request -> ok().syncBody("Home page"));
}
}
我们的应用使用功能性的 Web 框架来返回首页的简单消息。
com/zetcode/Application.java
package com.zetcode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Application
设置 Spring Boot 应用
com/zetcode/routes/AppRoutesTest.java
package com.zetcode.routes;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AppRoutesTest {
@Autowired
private WebTestClient client;
@Test
public void test_home_page() {
client.get().uri("/").exchange().expectStatus().isOk()
.expectBody(String.class).isEqualTo("Home page");
}
}
使用WebTestClient
,我们为主页创建一种测试方法。
...
2019-06-21 16:40:45.214 INFO 9356 --- [ctor-http-nio-5] com.zetcode.event.AppEvents : TimeResponse{date='06-21-2019', unixtime=null, time='02:40:47 PM'}
...
当应用启动时,我们将此消息发送到终端。