Java项目工作流完成后的通知触发器方案
在Java项目中实现工作流完成后的邮件或短信通知,可以使用多种触发器方案,MQ(消息队列)确实是其中一种很好的实现方式。
使用MQ实现通知触发
消息队列(MQ)非常适合这种异步通知场景,因为它可以解耦工作流处理和通知发送,提高系统的可靠性和扩展性。
常用MQ选择
- RabbitMQ
- Apache Kafka
- ActiveMQ
- RocketMQ
实现示例(以RabbitMQ为例)
1. 工作流完成后发送MQ消息
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class WorkflowService {
@Autowired
private RabbitTemplate rabbitTemplate;
public void completeWorkflow(String workflowId, String result) {
// 1. 完成工作流处理逻辑
// ...
// 2. 发送通知消息到MQ
NotificationMessage message = new NotificationMessage(
workflowId,
"Workflow completed",
result,
"user@example.com",
"13800138000"
);
rabbitTemplate.convertAndSend(
"workflow.exchange",
"workflow.completed",
message
);
System.out.println("Workflow completed notification sent to MQ");
}
}
2. 通知消费者处理消息并发送邮件/短信
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class NotificationConsumer {
@Autowired
private EmailService emailService;
@Autowired
private SmsService smsService;
@RabbitListener(queues = "workflow.completed.queue")
public void handleNotification(NotificationMessage message) {
try {
// 发送邮件通知
emailService.sendEmail(
message.getEmail(),
message.getSubject(),
message.getContent()
);
// 发送短信通知
smsService.sendSms(
message.getPhone(),
"您的工作流" + message.getWorkflowId() + "已完成,结果:" + message.getContent()
);
System.out.println("Notifications sent successfully");
} catch (Exception e) {
// 处理发送失败的情况,可以记录日志或放入死信队列
System.err.println("Failed to send notifications: " + e.getMessage());
}
}
}
3. 消息对象
public class NotificationMessage implements Serializable {
private String workflowId;
private String subject;
private String content;
private String email;
private String phone;
// 构造方法、getter和setter
}
其他实现方案
1. Spring事件机制
// 定义事件
public class WorkflowCompletedEvent extends ApplicationEvent {
private String workflowId;
private String result;
public WorkflowCompletedEvent(Object source, String workflowId, String result) {
super(source);
this.workflowId = workflowId;
this.result = result;
}
// getters
}
// 发布事件
@Service
public class WorkflowService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void completeWorkflow() {
// 完成工作流...
eventPublisher.publishEvent(
new WorkflowCompletedEvent(this, "123", "SUCCESS")
);
}
}
// 监听事件
@Component
public class NotificationListener {
@EventListener
public void handleWorkflowCompleted(WorkflowCompletedEvent event) {
// 发送通知...
}
}
2. 定时任务轮询
@Scheduled(fixedRate = 60000) // 每分钟检查一次
public void checkCompletedWorkflows() {
List<Workflow> completed = workflowRepository.findByStatusAndNotNotified("COMPLETED");
completed.forEach(wf -> {
// 发送通知
notificationService.send(wf);
// 更新为已通知
wf.setNotified(true);
workflowRepository.save(wf);
});
}
方案对比
方案 | 优点 | 缺点 |
---|---|---|
MQ | 解耦彻底,可靠性高,支持重试和死信队列 | 需要额外MQ基础设施 |
Spring事件 | 实现简单,适合小型应用 | 同步执行,可靠性较低 |
定时轮询 | 实现简单 | 实时性差,数据库压力大 |
对于生产环境,推荐使用MQ方案,特别是当:
- 需要高可靠性
- 通知服务可能暂时不可用
- 有大量通知需要发送
- 需要削峰填谷
MQ提供了消息持久化、确认机制、重试机制等,能很好地保证通知最终被送达。