代码中使用了 Lombok 和 Slf4j,关于这两个库的具体使用,可以参考:
示例1:Spring Boot 的生命周期中有哪些事件
在 Spring Boot 的生命周期中,会有一些事件被抛出来。我们看下如何监听这些事件。
demo01 项目结构:
demo01
├── build.gradle
└── src
├── main
│ ├── java
│ │ └── demo
│ │ ├── ApplicationEventListener.java
│ │ └── Demo01Application.java
│ └── resources
│ └── application.properties
└── test
├── java
└── resources
主类 Demo01Application 。
package demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@Slf4j
public class Demo01Application implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
log.info("...run...");
}
public static void main(String[] args) {
SpringApplication.run(Demo01Application.class, args);
}
}
事件监听类 ApplicationEventListener:
package demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
@Slf4j
public class ApplicationEventListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
log.info("event name: {}", event);
}
}
application.properties
中配置监听类:
context.listener.classes=demo.ApplicationEventListener
执行主类,结果:
demo.Demo01Application : Starting Demo01Application on Myhost with PID 91846
demo.Demo01Application : No active profile set, falling back to default profiles: default
demo.ApplicationStartedEventListener : event name: org.springframework.boot.context.event.ApplicationPreparedEvent[source=org.springframework.boot.SpringApplication@3e77a1ed]
s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2b4a2ec7: startup date [Thu Aug 02 13:12:35 CST 2018]; root of context hierarchy
o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
demo.ApplicationStartedEventListener : event name: org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@2b4a2ec7: startup date [Thu Aug 02 13:12:35 CST 2018]; root of context hierarchy]
demo.Demo01Application : Started Demo01Application in 1.074 seconds (JVM running for 1.533)
demo.ApplicationStartedEventListener : event name: org.springframework.boot.context.event.ApplicationStartedEvent[source=org.springframework.boot.SpringApplication@3e77a1ed]
demo.Demo01Application : ...run...
demo.ApplicationStartedEventListener : event name: org.springframework.boot.context.event.ApplicationReadyEvent[source=org.springframework.boot.SpringApplication@3e77a1ed]
s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2b4a2ec7: startup date [Thu Aug 02 13:12:35 CST 2018]; root of context hierarchy
demo.ApplicationStartedEventListener : event name: org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@2b4a2ec7: startup date [Thu Aug 02 13:12:35 CST 2018]; root of context hierarchy]
o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
可以看到,有 ApplicationPreparedEvent
、ContextRefreshedEvent
、ApplicationStartedEvent
ApplicationReadyEvent
、ContextClosedEvent
被监听到。
示例2:通过实现 ApplicationListener 接口监听事件
示例1中已经是监听事件了。如果要监听摸一个具体的事件,该怎么做?
实现 ApplicationListener 接口,并在泛型中指定事件类型即可。
demo02 项目结构:
demo02
├── build.gradle
└── src
├── main
│ ├── java
│ │ └── demo
│ │ ├── ApplicationStartedEventListener.java
│ │ └── Demo02Application.java
│ └── resources
└── test
├── java
└── resources
注意,没有application.properties
文件了。
类 ApplicationStartedEventListener :
package demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class ApplicationStartedEventListener implements ApplicationListener<ApplicationStartedEvent> {
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
log.info("{} ApplicationStartedEvent", getClass().getSimpleName());
}
}
实现 ApplicationListener 接口,并指明要监听的事件即可。
主类 Demo02Application :
package demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@Slf4j
public class Demo02Application implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
log.info("...run...");
}
public static void main(String[] args) {
SpringApplication.run(Demo02Application.class, args);
}
}
执行主类:
demo.ApplicationStartedEventListener : ApplicationStartedEventListener ApplicationStartedEvent
demo.Demo02Application : ...run...
示例3:使用 @EventListener 注解监听特定事件
这次使用 @EventListener 监听事件。
demo03 项目结构:
demo03
├── build.gradle
└── src
├── main
│ ├── java
│ │ └── demo
│ │ ├── ApplicationStartedEventListener.java
│ │ └── Demo03Application.java
│ └── resources
└── test
├── java
└── resources
package demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class ApplicationStartedEventListener {
@EventListener
public void handleApplicationStartedEvent(ApplicationStartedEvent event) {
log.info("{} ApplicationStartedEvent", getClass().getSimpleName());
}
}
运行主类 Demo03Application :
demo.ApplicationStartedEventListener : ApplicationStartedEventListener ApplicationStartedEvent
demo.Demo03Application : ...run...
demo04 - 自定义事件,并发布事件
demo04 项目结构:
demo04
├── build.gradle
└── src
├── main
│ ├── java
│ │ └── demo
│ │ ├── Demo04Application.java
│ │ ├── EventHandler.java
│ │ └── MyEvent.java
│ └── resources
└── test
├── java
└── resources
自定义事件 MyEvent:
package demo;
public class MyEvent {
private String msg;
public MyEvent(String msg) {
this.msg = msg;
}
public String getMsg() {
return this.msg;
}
}
EventHandler 类 用来监听事件:
package demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class EventHandler {
@EventListener
public void handleMyEvent(MyEvent event) {
log.info("{} handleMyEvent msg: {}", getClass().getSimpleName(), event.getMsg());
}
}
主类 Demo04Application 在 Spring 启动后发布事件:
package demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationEventPublisher;
@SpringBootApplication
@Slf4j
public class Demo04Application implements CommandLineRunner {
@Autowired
public ApplicationEventPublisher publisher;
@Override
public void run(String... args) throws Exception {
log.info("...run...");
publisher.publishEvent(new MyEvent("Hello World"));
}
public static void main(String[] args) {
SpringApplication.run(Demo04Application.class, args);
}
}
运行结果:
demo.Demo04Application : ...run...
demo.EventHandler : EventHandler handleMyEvent msg: Hello World