Spring中事件的发布订阅
一、介绍
在Spring框架中,ApplicationEventPublisher
是一个接口,用于发布应用程序事件。它允许应用程序的不同组件之间进行解耦,实现事件驱动的开发模式。
通过ApplicationEventPublisher,我们可以将自定义的事件发布到应用程序的上下文中,然后其他组件可以注册为ApplicationListener
来监听这些事件。ApplicationListener是另一个接口,用于接收和处理应用程序事件。
当事件被发布时,ApplicationEventPublisher
会通知所有注册的ApplicationListener
,并将事件对象传递给它们。这样,监听器就可以根据事件的类型进行相应的处理逻辑,完成业务逻辑的触发和处理。
使用ApplicationEventPublisher
和ApplicationListener
可以实现松耦合的事件驱动编程,提高代码的可维护性和扩展性。它们是Spring框架中事件机制的核心组件之一。
不啰嗦,直接看如何编写代码
二、代码
声明一个事件,TestEvent.java
,需要继承ApplicationEvent.java
,并传递一个对象
1 2 3 4 5 6 7 8 9 10 11 12
| package com.banmoon.event.test;
import com.banmoon.obj.request.TestEventRequest; import org.springframework.context.ApplicationEvent;
public class TestEvent extends ApplicationEvent {
public TestEvent(TestEventRequest dto) { super(dto); }
}
|
这边这个对象,选择了TestEventRequest,java
,里面可以放事件相关的属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.banmoon.obj.request;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data @ApiModel("发布订阅测试-入参") public class TestEventRequest {
@NotBlank @ApiModelProperty(value = "名称标识", required = true) private String name;
@NotBlank @ApiModelProperty(value = "说明", required = true) private String description;
}
|
事件有了,如何进行发布呢?自己注入直接使用ApplicationEventPublisher.java
也行,这边选择实现ApplicationEventPublisherAware.java
。都是一样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.banmoon.event;
import lombok.Data; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.stereotype.Component;
import javax.annotation.Nonnull;
@Data @Component public class BanmoonApplicationEventPublisherAware implements ApplicationEventPublisherAware {
private ApplicationEventPublisher applicationEventPublisher;
@Override public void setApplicationEventPublisher(@Nonnull ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; }
public void publishEvent(ApplicationEvent event) { applicationEventPublisher.publishEvent(event); } }
|
发布有了,订阅来看看TestListener.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.banmoon.event.test;
import com.banmoon.obj.request.TestEventRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component;
@Slf4j @Component public class TestListener {
@EventListener(TestEvent.class) public void listener(TestEvent event) { TestEventRequest dto = (TestEventRequest) event.getSource(); log.info("订阅监听消息:{}", dto); }
}
|
三、测试
来测试一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| package com.banmoon.controller;
import com.banmoon.business.obj.dto.ResultData; import com.banmoon.event.BanmoonApplicationEventPublisherAware; import com.banmoon.event.test.TestEvent; import com.banmoon.obj.request.TestEventRequest; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.validation.Valid;
@Slf4j @Validated @Api(tags = "发布订阅测试") @RestController @RequestMapping("/event") public class TestEventController {
@Resource private BanmoonApplicationEventPublisherAware applicationEventPublisherAware;
@ApiOperation("发布测试事件") @PostMapping("/publishTestEvent") public ResultData<Void> publishTestEvent(@RequestBody @Valid TestEventRequest req) { TestEvent testEvent = new TestEvent(req); applicationEventPublisherAware.publishEvent(testEvent); return ResultData.success(); }
}
|
四、最后
我是半月,你我一同共勉