砍材农夫砍材农夫
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • llm wiki

    • 基于karpathy
    • gradle
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • 环境配置
    • 微信生态
    • 正则
    • 全栈技能
  • java圈

    • java基础
    • jdk体系
    • jvm
    • spring框架
    • 分库分表
    • zookeeper
  • python技能

    • python编程
    • python数据
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • AIoT
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • devops
  • 元宇宙
  • 区块链
  • 物联网
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • llm wiki

    • 基于karpathy
    • gradle
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • 环境配置
    • 微信生态
    • 正则
    • 全栈技能
  • java圈

    • java基础
    • jdk体系
    • jvm
    • spring框架
    • 分库分表
    • zookeeper
  • python技能

    • python编程
    • python数据
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • AIoT
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • devops
  • 元宇宙
  • 区块链
  • 物联网
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • spring_boot

    • SpEL(表达式)

      • 概念
      • 常用命令
      • nginx安装和部署
  • spring_cloud

    • 入门

      • SpEL(表达式)

        • 概念
        • 常用命令
        • nginx安装和部署
  • spring_core

    • SpEL(表达式)

      • 概念
      • 常用命令
      • nginx安装和部署
    • spring event

      • spring event入门
      • spring event高性能
      • spring event顺序和条件
      • spring event泛化
  • spring_tools

    • 入门

      • SpEL(表达式)

        • 概念
        • 常用命令
        • nginx安装和部署
  • spring|spring event高性能|Spring内置事件驱动编程模型
    • 从同步阻塞到异步非阻塞
    • 源码
    • 开启异步
    • 异步样例
      • 启动类
      • 两种不同的监听方式(通过注释来分别调试异步和同步)
      • 验证地址
      • 验证结果
      • 当前方式存在的问题
    • 自定义异步线程池
      • 优化调整,显示指定线程池

spring|spring event高性能|Spring内置事件驱动编程模型

从同步阻塞到异步非阻塞

默认是同步且阻塞,发布线程会串行依次执行所有监听器。任何一个监听器的耗时操作都会阻塞主流程,可能导致严重的性能问题

源码

https://gitee.com/jysemel-spring/spring-boot/tree/master/action/action-event-async

开启异步

  • 启用异步支持

配置类上添加@EnableAsync注解

  • 标记异步监听器
@Component
public class AsyncNotificationListener {
    @Async
    @EventListener
    public void handleUserRegisteredEvent(UserRegisteredEvent event) {
        // 此逻辑将在独立线程中执行
        System.out.println("异步发送欢迎邮件给用户:" + event.getUserId());
    }
}

异步样例

启动类

package com.jysemel.spring.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@SpringBootApplication
public class Main {
    public static void main(String[] args) {

        SpringApplication.run(Main.class, args);
    }
}

两种不同的监听方式(通过注释来分别调试异步和同步)

package com.jysemel.spring.boot.study.listener;


import com.jysemel.spring.boot.study.event.UserRegisteredEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 方式二:使用@EventListener注解(更推荐)
 */
@Slf4j
@Component
public class CouponListener {


    @Async
    @EventListener
    public void handleUserRegisteredEvent(UserRegisteredEvent event) throws InterruptedException {
        log.info("方式二:使用@EventListener注解 @Async异步监听处理 ");
        try {
            Thread.sleep(TimeUnit.MINUTES.toMillis(5));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("赠送新人优惠券给用户:{} ", event.getNickName());
    }
}
package com.jysemel.spring.boot.study.listener;

import com.jysemel.spring.boot.study.event.UserRegisteredEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;


/**
 * 方式一:实现ApplicationListener接口
 */
@Slf4j
@Component
public class WelcomeEmailListener implements ApplicationListener<UserRegisteredEvent> {


    @Override
    public void onApplicationEvent(UserRegisteredEvent event) {
        log.info("方式一:普通监听 ");
        try {
            Thread.sleep(TimeUnit.MINUTES.toMillis(5));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("发送欢迎邮件给用户: {}" ,event.getNickName());
    }
}

验证地址

http://127.0.0.1:8083/api/user/reg?userName=113.9526&nickName=22.5431

验证结果

  • 异步方式,线程id不一样
2026-07-14 11:49:13.600 [http-nio-8083-exec-1] [] INFO  com.jysemel.spring.boot.study.controller.UserRegController - 用户注册:113.9526
2026-07-14 11:49:13.600 [http-nio-8083-exec-1] [] INFO  com.jysemel.spring.boot.study.service.StoreService - 用户 22.5431   注册成功
2026-07-14 11:49:13.602 [task-2] [] INFO  com.jysemel.spring.boot.study.listener.CouponListener - 方式二:使用@EventListener注解 @Async异步监听处理 
2026-07-14 11:49:14.402 [http-nio-8083-exec-2] [] INFO  com.jysemel.spring.boot.study.controller.UserRegController - 用户注册:113.9526
2026-07-14 11:49:14.402 [http-nio-8083-exec-2] [] INFO  com.jysemel.spring.boot.study.service.StoreService - 用户 22.5431   注册成功
2026-07-14 11:49:14.403 [task-3] [] INFO  com.jysemel.spring.boot.study.listener.CouponListener - 方式二:使用@EventListener注解 @Async异步监听处理 
  • 同步方式,线程id一样,上面接口明显阻塞
2026-07-14 11:52:39.886 [http-nio-8083-exec-1] [] INFO  org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-07-14 11:52:39.886 [http-nio-8083-exec-1] [] INFO  org.springframework.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2026-07-14 11:52:39.889 [http-nio-8083-exec-1] [] INFO  org.springframework.web.servlet.DispatcherServlet - Completed initialization in 3 ms
2026-07-14 11:52:39.928 [http-nio-8083-exec-1] [] INFO  com.jysemel.spring.boot.study.controller.UserRegController - 用户注册:113.9526
2026-07-14 11:52:39.930 [http-nio-8083-exec-1] [] INFO  com.jysemel.spring.boot.study.service.StoreService - 用户 22.5431   注册成功
2026-07-14 11:52:39.931 [http-nio-8083-exec-1] [] INFO  com.jysemel.spring.boot.study.listener.WelcomeEmailListener - 方式一:普通监听 

当前方式存在的问题

  • 队列无限大
  • 无线程复用 img

自定义异步线程池

package com.jysemel.spring.boot.study.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class AsyncConfig {

    @Bean(name = "eventExecutor")
    public Executor eventExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);                // 核心线程数
        executor.setMaxPoolSize(20);                // 最大线程数(必须小于操作系统限制)
        executor.setQueueCapacity(200);             // 有界队列,防止OOM
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("event-async-");
        // 关键:当队列和最大线程都满了,由调用者线程执行(防止任务丢失,并提供背压机制)
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

img

优化调整,显示指定线程池

package com.jysemel.spring.boot.study.listener;


import com.jysemel.spring.boot.study.event.UserRegisteredEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 方式二:使用@EventListener注解(更推荐)
 */
@Slf4j
@Component
public class CouponListener {


    @Async("eventExecutor")
    @EventListener
    public void handleUserRegisteredEvent(UserRegisteredEvent event) throws InterruptedException {
        log.info("方式二:使用@EventListener注解 @Async异步监听处理 ");
        try {
            Thread.sleep(TimeUnit.SECONDS.toMillis(10));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("赠送新人优惠券给用户:{} ", event.getNickName());
    }
}
最近更新: 2026/7/16 15:24
Contributors: kcnf
Prev
spring event入门
Next
spring event顺序和条件