Spring的事件机制是基于观察者模式的实现,主要由以下三个部分组成:
事件(Event):事件是应用中发生的重要事情,通常是一个继承自ApplicationEvent的类。
事件发布器(Publisher):发布事件的对象,通常是Spring的应用上下文(ApplicationContext)。
事件监听器(Listener):监听并处理事件的对象,通常是实现了ApplicationListener接口的类。
- 同步方法
- 创建自定义事件,自定义事件需要继承ApplicationEvent类,并添加相应的属性和构造方法
package com.ssdl.baize.pub;
import org.springframework.context.ApplicationEvent;
public class CustomEvent extends ApplicationEvent {
private String message;
public CustomEvent(Object source, String message) {
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
}
- 创建事件监听器,用于监听和处理自定义事件。事件监听器需要实现ApplicationListener接口,并覆盖onApplicationEvent方法。
package com.ssdl.baize.pub;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class CustomEventListener implements ApplicationListener<CustomEvent> {
@Override
public void onApplicationEvent(CustomEvent event) {
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("休眠5秒");
log.info("Received custom event - {}" , event.getMessage());
}
}
3.发布事件,要在某个组件中注入ApplicationEventPublisher,并调用其publishEvent方法。
package com.ssdl.baize.pub;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class CustomEventPublisher {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void publishEvent(String message) {
CustomEvent customEvent = new CustomEvent(this, message);
applicationEventPublisher.publishEvent(customEvent);
}
}
4.测试
@Autowired
private CustomEventPublisher customEventPublisher;
@GetMapping(path = "/pub")
@ApiOperation(value = "发布订阅")
public String pub(@RequestParam("message") String message) {
log.info("start");
customEventPublisher.publishEvent(message);
log.info("发送完成!!!");
return "OK";
}
5.结果
- 异步方法
说明:创建自定义事件、发布事件、测试这三个如同步方法一样,只需要更改创建事件监听器即可
package com.ssdl.baize.pub;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
@EnableAsync
public class AsyncConfig {
}
package com.ssdl.baize.pub;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class AsyncCustomEventListener {
@Async
@EventListener(condition = "#event.message.startsWith('filter')")
public void handleCustomEvent(CustomEvent event) {
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("休眠5秒");
log.info("Async received custom event - {}" , event.getMessage());
}
}
注:condition 限制只接收filter开头的消息
结果: