简单的使用:
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());
}
}
- 解耦:事件的发布者和监听者之间没有直接依赖关系,通过事件总线进行通信,实现了松耦合。
- 扩展性:可以轻松地添加新的事件处理逻辑,而不需要修改现有的代码。
- 可维护性:事件驱动架构使得代码结构更加清晰,职责划分更加明确,提升了代码的可维护性。
- 异步处理:可以通过异步事件处理提升系统的响应速度和吞吐量。
参考文章:
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