Spring Event事件发布&消费Demo
demo基于springboot maven项目
spring event默认是同步执行的,因此后面示范了如何异步执行事件的监听函数,以及配置自己的异步线程池
pom.xml
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--spring web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springboot devtools-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- spring configuration processor-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
实现自己的事件
package com.example.demo.event;
import lombok.Getter;
import lombok.ToString;
import org.springframework.context.ApplicationEvent;
/**
* @Author humorchen
* @Date 2021/10/25
*/
@Getter
@ToString
public class NoticeEvent extends ApplicationEvent {
/**
* 标题
*/
private String title;
/**
* 内容
*/
private String content;
public NoticeEvent(String title,String content) {
super(title);
this.title = title;
this.content = content;
}
}
定义事件监听器
package com.example.demo.listener;
import com.example.demo.event.NoticeEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* @Author humorchen
* @Date 2021/10/25
*/
@Component
public class NoticeEventListener implements ApplicationListener<NoticeEvent> {
@Async
@Override
public void onApplicationEvent(NoticeEvent noticeEvent) {
System.out.println(Thread.currentThread().getName() + "线程处理事件");
System.out.println(noticeEvent);
}
}
定义事件发布接口
package com.example.demo.controller;
import com.example.demo.event.NoticeEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author humorchen
* @Date 2021/10/25
*/
@RestController
public class EventPublisherController {
/**
* 注入spring 事件发布器
*/
@Autowired
private ApplicationEventPublisher eventPublisher;
@RequestMapping("/publish")
public String publish(String title,String content){
NoticeEvent event = new NoticeEvent(title,content);
System.out.println("接口收到请求,内容如下:");
System.out.println(event);
eventPublisher.publishEvent(event);
String ret = "事件发布成功";
System.out.println(ret);
return ret;
}
}
走异步线程池执行监听函数
- 给启动类加@EnableAsync注解
- 给消费函数加@Async注解
定义自己的spring异步线程池
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
* @Author humorchen
* @Date 2021/10/25
*/
@Configuration
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(16);
executor.setQueueCapacity(Integer.MAX_VALUE);
executor.setThreadNamePrefix("async-thread-");
executor.initialize();
return executor;
}
}
发送请求
http://localhost/publish?title=放假&content=明天放假
执行结果
接口收到请求,内容如下:
NoticeEvent(title=放假, content=明天放假)
2021-10-25 15:30:04.414 INFO 10088 --- [p-nio-80-exec-1] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService
事件发布成功
async-thread-1线程处理事件
NoticeEvent(title=放假, content=明天放假)