1, Introduction
1. Basic principles of Spring event monitoring
Spring's event listening mechanism is very similar to the publish subscribe mechanism: after publishing an event, all listeners listening to this type of event will trigger the corresponding processing logic.
As stated in the official document of Spring, it is an observer mode. Then, we might as well guess how Spring implements event publishing and listening: the bottom layer uses a set to store all listeners. When an event is published, traverse the event listener set, then filter the listeners that match the event type, and finally trigger the corresponding event processing logic.
2. Relevant specifications of event listening in Spring
In Spring, the event listening mechanism mainly involves the following key specifications (abstract classes and interfaces): ApplicationEvent, ApplicationListener, ApplicationEventPublisher
-
ApplicationEvent: Spring events conform to the jdk specification. This abstract class inherits the event specification class EventObject built into jdk (that is, jdk recommends that all events inherit the EventObject class). ApplicationEvent is the event specification of Spring family. So when customizing events, we can inherit from ApplicationEvent. For example, the Spring family defines a time specification ApplicationContextEvent for container context events, which also inherits from ApplicationEvent, but extends the method of obtaining the container that sends events; In the future, we can also define our own event specifications based on ApplicationEvent.
-
ApplicationListener: This is a functional interface, which is also the specification of event listeners. When you hear the event type you are listening to, you will call onApplicationEvent method to execute the listening logic
-
ApplicationEventPublisher: This is also a functional interface that defines the specification of event publishing. Any event publisher ApplicationEventPublisher publishes events by calling publishEvent
2, Use of Spring event listeners
1. Custom event creation
In Spring, all events need to be inherited from ApplicationEvent. Different custom events can listen to multiple ones. The most basic MsgEvent is as follows
public class MyEvent extends ApplicationEvent { private String msg; // Must inherit implementation public MyEvent(Object source, String msg) { super(source); this.msg = msg; } @Override public String toString() { return "MyEvent{" + "msg='" + msg + '\'' + '}'; } }
2. Custom listener
2.1 method introduction
There are four ways for springboot to listen to events, just choose any one
-
Load listeners into spring containers (common)
-
Realize event listening through @EventListener annotation (common)
-
Add listeners to ApplicationContext manually
-
Configure listeners in application.properties
2.2 loading listeners into spring containers
// Load into spring container @Slf4j @Component public class MyListener1 implements ApplicationListener<MyEvent> { @Override public void onApplicationEvent(MyEvent event) { // You can customize your own method here log.info(String.format("%s Listen to the event source:%s.", MyListener1.class.getName(), event.toString())); } }
If you do not add the @Component annotation to the Spring container, you can also add it manually
@SpringBootApplication public class ListenerApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(ListenerApplication.class, args); //Load monitor context.addApplicationListener(new MyListener1()); } }
You can also configure listeners in the configuration document application.properties: context.listener.classes=com.listener.MyListener1
2.3 the @eventlistener annotation implements event listening
@Component @Slf4j public class MyListener2{ // Method of annotation @EventListener(MyEvent.class) public void consumer(MyEvent msgEvent) { log.info(String.format("%s Listen to the event source:%s.", MsgPublisher.class.getName(), msgEvent.toString())); } }
3. Event release
The first is the consumption event. The premise of consumption is that there is an event. In Spring, publishing events mainly requires the help of ApplicationContext
@Component @Slf4j public class MsgPublisher implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } // Initiate event notification public void publish(String msg) { applicationContext.publishEvent(new MyEvent1(this, msg)); } // Method of annotation @EventListener(MyEvent.class) public void consumer(MyEvent msgEvent) { log.info(String.format("%s Listen to the event source:%s.", MsgPublisher.class.getName(), msgEvent.toString())); } /** * This is just a test. spring can call it directly at that time */ public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(MsgPublisher.class); MsgPublisher msgPublisher = context.getBean(MsgPublisher.class); msgPublisher.publish("hello world"); } }