在Spring框架中,ApplicationEventPublisher
是一个接口,用于发布应用程序事件。它允许应用程序的不同组件之间进行解耦,实现事件驱动的开发模式。
通过ApplicationEventPublisher,我们可以将自定义的事件发布到应用程序的上下文中,然后其他组件可以注册为ApplicationListener
来监听这些事件。ApplicationListener是另一个接口,用于接收和处理应用程序事件。
当事件被发布时,ApplicationEventPublisher
会通知所有注册的ApplicationListener
,并将事件对象传递给它们。这样,监听器就可以根据事件的类型进行相应的处理逻辑,完成业务逻辑的触发和处理。
使用ApplicationEventPublisher
和ApplicationListener
可以实现松耦合的事件驱动编程,提高代码的可维护性和扩展性。它们是Spring框架中事件机制的核心组件之一。
不啰嗦,直接看如何编写代码
声明一个事件,TestEvent.java
,需要继承ApplicationEvent.java
,并传递一个对象
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
,里面可以放事件相关的属性
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
。都是一样的
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
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);
}
}
来测试一下
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();
}
}
我是半月,你我一同共勉