Spring is a very simple way to implement event listening. This article briefly introduces two approaches to interface and annotation listening

Two consumption postures for the event mechanism

I. Project environment

This project is developed by SpringBoot 2.2.1.RELEASE + Maven 3.5.3 + IDEA

Start a Web service for later publication event validation

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
Copy the code

II. Event mechanism

1. Event objects

In Spring, all events need to be derived from ApplicationEvent. A basic MsgEvent is as follows

public class MsgEvent extends ApplicationEvent {
    private String msg;

    /**
     * Create a new {@code ApplicationEvent}.
     *
     * @param source the object on which the event initially occurred or with
     *               which the event is associated (never {@code null})
     */
    public MsgEvent(Object source, String msg) {
        super(source);
        this.msg = msg;
    }

    @Override
    public String toString(a) {
        return "MsgEvent{" +
                "msg='" + msg + '\' ' +
                '} '; }}Copy the code

2. Interface consumption

There are two ways to consume events. The declaration of interfaces is mainly to implement the ApplicationListener interface. Notice that the Listener needs to be declared as a Spring bean object

@Service
public class MsgEventListener implements ApplicationListener<MsgEvent> {
    @Override
    public void onApplicationEvent(MsgEvent event) {
        System.out.println("receive msg event: "+ event); }}Copy the code

3. Annotated consumption

Implementing the interface requires creating a new implementation class. It is easier to simply add an annotation @EventListener to the consuming method

@EventListener(MsgEvent.class)
public void consumer(MsgEvent msgEvent) {
    System.out.println("receive msg by @anno: " + msgEvent);
}
Copy the code

This annotation supports matching by Event parameter type, i.e. in the example above, @eventListener is added directly to the method without specifying parentheses

4. Publish events

In Spring, the main way to publish an event is to use the ApplicationContext

@Service
public class MsgPublisher implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void publish(String msg) {
        applicationContext.publishEvent(new MsgEvent(this, msg)); }}Copy the code

5. Test

A simple test demo

@RestController
public class IndexController {
    @Autowired
    private MsgPublisher msgPublisher;

    @GetMapping(path = "pub")
    public String publish(String msg) {
        msgPublisher.publish(msg);
        return "ok"; }}Copy the code

Access: curl http://localhost:8082/pub? MSG = a dusty blog

Output log:

Receive MSG by @anno: MsgEvent{MSG =' MSG '} receive MSG by @anno: MsgEvent{MSG =' MSG '}Copy the code

The above test can be successful for both consumption methods. However, in the process of actual measurement, a case was found that the consumption method was not effective. The test posture is as follows

@SpringBootApplication
public class Application {

    public Application(MsgPublisher msgPublisher) {
        msgPublisher.publish("A Gray Blog");
    }
    public static void main(String[] args) { SpringApplication.run(Application.class); }}Copy the code

Publish the event directly in the constructor of the initializer class. Find that the interface mode can receive the event, but the annotation mode does not take effect.

Have a similar problem on stockoverstack stackoverflow.com/questions/3… Here is the main point of view

  • Publish messages before event consumption is registered

Is that the reason? Wait for the next source code analysis

II. The other

0. Project

  • Project: github.com/liuyueyi/sp…
  • Source: github.com/liuyueyi/sp…

1. An ashy Blog

As far as the letter is not as good, the above content is purely one’s opinion, due to the limited personal ability, it is inevitable that there are omissions and mistakes, if you find bugs or have better suggestions, welcome criticism and correction, don’t hesitate to appreciate

Below a gray personal blog, record all the study and work of the blog, welcome everyone to go to stroll

  • A grey Blog Personal Blog blog.hhui.top
  • A Grey Blog-Spring feature Blog Spring.hhui.top
  • Wechat official account: One Grey Blog