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> {@Overridepublic 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 {@Autowiredprivate ApplicationEventPublisher applicationEventPublisher;public void publishEvent(String message) {CustomEvent customEvent = new CustomEvent(this, message);applicationEventPublisher.publishEvent(customEvent);}
}
4.测试
@Autowiredprivate 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开头的消息
结果: