springBoot 事件驱动开发

我爱海鲸 2025-01-20 10:02:27 暂无标签

简介event、异步

简单的使用:

log.info("触发登录成功事件");
			SpringUtil.publishEventThrowable(new LoginSuccessEvent(user.getId().toString()));



public class LoginSuccessEvent extends ApplicationEvent {

    public LoginSuccessEvent(String phone) {
        super(phone);
    }
}


@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Component
public class LoginSuccessListener {

    @EventListener(LoginSuccessEvent.class)
    public void loginEvent(LoginSuccessEvent event) {
        String userId = (String) event.getSource();
        // 处理业务逻辑
    }

}

自定义事件:

import org.springframework.context.ApplicationEvent;
public class UserRegisteredEvent extends ApplicationEvent {
    private String username;
    public UserRegisteredEvent(Object source, String username) {
        super(source);
        this.username = username;
    }
    public String getUsername() {
        return username;
    }
}

发布事件

import cn.juwatech.event.UserRegisteredEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
@Service
public class UserService {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;
    public void registerUser(String username) {
        // 用户注册逻辑
        System.out.println("User registered: " + username);
        // 发布事件
        UserRegisteredEvent event = new UserRegisteredEvent(this, username);
        applicationEventPublisher.publishEvent(event);
    }
}

监听事件

import cn.juwatech.event.UserRegisteredEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
public class UserRegisteredListener {
    @EventListener
    public void handleUserRegisteredEvent(UserRegisteredEvent event) {
        // 发送欢迎邮件
        System.out.println("Sending welcome email to " + event.getUsername());
        
        // 记录日志
        System.out.println("Logging user registration: " + event.getUsername());
    }
}
  • 解耦:事件的发布者和监听者之间没有直接依赖关系,通过事件总线进行通信,实现了松耦合。
  • 扩展性:可以轻松地添加新的事件处理逻辑,而不需要修改现有的代码。
  • 可维护性:事件驱动架构使得代码结构更加清晰,职责划分更加明确,提升了代码的可维护性。
  • 异步处理:可以通过异步事件处理提升系统的响应速度和吞吐量。

参考文章:

Spring Boot中的事件驱动开发-阿里云开发者社区

2025-01-20 start:

异步事件:添加如下配置

@Configuration
@EnableAsync
public class SyncConfiguration {
    @Bean(name = "asyncPoolTaskExecutor")
    public ThreadPoolTaskExecutor executor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //核心线程数
        taskExecutor.setCorePoolSize(10);
        //线程池维护线程的最大数量,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        taskExecutor.setMaxPoolSize(100);
        //缓存队列
        taskExecutor.setQueueCapacity(50);
        //许的空闲时间,当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
        taskExecutor.setKeepAliveSeconds(200);
        //异步方法内部线程名称
        taskExecutor.setThreadNamePrefix("async-");
        /**
         * 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略
         * 通常有以下四种策略:
         * ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
         * ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
         * ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
         * ThreadPoolExecutor.CallerRunsPolicy:重试添加当前的任务,自动重复调用 execute() 方法,直到成功
         */
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        taskExecutor.initialize();
        return taskExecutor;
    }
}

异步注解:

@Component
public class AddCreditEventListener implements ApplicationListener<AddCreditEvent> {
    
    @Override
    @Async
    public void onApplicationEvent(AddCreditEvent event) {
        Object source = event.getSource();
        AddCreditDTO addCreditDTO = (AddCreditDTO)source;
        //新增积分业务代码
        ....
    }
}

end

你好:我的2025