本文目录导读:

我将为您提供一个完整的Java通知系统实现案例,包含多种通知渠道和灵活的设计模式。
核心接口设计
// 通知接口
public interface Notifier {
void send(Notification notification);
boolean supports(NotificationType type);
}
// 通知类型枚举
public enum NotificationType {
EMAIL, SMS, PUSH, WECHAT, SYSTEM
}
// 通知状态
public enum NotificationStatus {
PENDING, SENT, FAILED, RETRYING
}
通知实体类
// 通知类
public class Notification {
private String id;
private String title;
private String content;
private List<String> receivers;
private NotificationType type;
private NotificationStatus status;
private Map<String, Object> additionalData;
private LocalDateTime createTime;
private LocalDateTime sendTime;
private int retryCount;
// 使用建造者模式
public static class Builder {
private Notification notification = new Notification();
public Builder id(String id) {
notification.id = id;
return this;
}
public Builder title(String title) {
notification.title = title;
return this;
}
public Builder content(String content) {
notification.content = content;
return this;
}
public Builder receivers(List<String> receivers) {
notification.receivers = receivers;
return this;
}
public Builder type(NotificationType type) {
notification.type = type;
return this;
}
public Builder additionalData(Map<String, Object> data) {
notification.additionalData = data;
return this;
}
public Notification build() {
notification.createTime = LocalDateTime.now();
notification.status = NotificationStatus.PENDING;
notification.retryCount = 0;
return notification;
}
}
// Getters and Setters
// ... (省略具体实现)
}
具体通知实现
// 邮件通知
public class EmailNotifier implements Notifier {
private static final Logger logger = LoggerFactory.getLogger(EmailNotifier.class);
private JavaMailSender mailSender;
private TemplateEngine templateEngine;
public EmailNotifier(JavaMailSender mailSender, TemplateEngine templateEngine) {
this.mailSender = mailSender;
this.templateEngine = templateEngine;
}
@Override
public void send(Notification notification) {
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setTo(notification.getReceivers().toArray(new String[0]));
helper.setSubject(notification.getTitle());
helper.setText(buildEmailContent(notification), true);
mailSender.send(message);
notification.setStatus(NotificationStatus.SENT);
notification.setSendTime(LocalDateTime.now());
logger.info("邮件通知发送成功: {}", notification.getId());
} catch (Exception e) {
logger.error("邮件通知发送失败: {}", notification.getId(), e);
notification.setStatus(NotificationStatus.FAILED);
throw new NotificationException("邮件发送失败", e);
}
}
private String buildEmailContent(Notification notification) {
Context context = new Context();
context.setVariable("title", notification.getTitle());
context.setVariable("content", notification.getContent());
return templateEngine.process("notification-template", context);
}
@Override
public boolean supports(NotificationType type) {
return type == NotificationType.EMAIL;
}
}
// 短信通知
public class SmsNotifier implements Notifier {
private static final Logger logger = LoggerFactory.getLogger(SmsNotifier.class);
private SmsService smsService;
private String templateId;
public SmsNotifier(SmsService smsService, String templateId) {
this.smsService = smsService;
this.templateId = templateId;
}
@Override
public void send(Notification notification) {
try {
for (String receiver : notification.getReceivers()) {
SmsRequest request = new SmsRequest();
request.setPhone(receiver);
request.setTemplateId(templateId);
request.setParams(buildSmsParams(notification));
smsService.sendSms(request);
}
notification.setStatus(NotificationStatus.SENT);
notification.setSendTime(LocalDateTime.now());
logger.info("短信通知发送成功: {}", notification.getId());
} catch (Exception e) {
logger.error("短信通知发送失败: {}", notification.getId(), e);
notification.setStatus(NotificationStatus.FAILED);
throw new NotificationException("短信发送失败", e);
}
}
private Map<String, String> buildSmsParams(Notification notification) {
Map<String, String> params = new HashMap<>();
params.put("title", notification.getTitle());
params.put("content", notification.getContent());
return params;
}
@Override
public boolean supports(NotificationType type) {
return type == NotificationType.SMS;
}
}
// 站内信通知
public class SystemNotifier implements Notifier {
private static final Logger logger = LoggerFactory.getLogger(SystemNotifier.class);
private UserMessageRepository messageRepository;
public SystemNotifier(UserMessageRepository messageRepository) {
this.messageRepository = messageRepository;
}
@Override
public void send(Notification notification) {
try {
for (String receiver : notification.getReceivers()) {
UserMessage message = new UserMessage();
message.setUserId(receiver);
message.setTitle(notification.getTitle());
message.setContent(notification.getContent());
message.setRead(false);
message.setCreateTime(LocalDateTime.now());
messageRepository.save(message);
}
notification.setStatus(NotificationStatus.SENT);
notification.setSendTime(LocalDateTime.now());
logger.info("站内信通知发送成功: {}", notification.getId());
} catch (Exception e) {
logger.error("站内信通知发送失败: {}", notification.getId(), e);
notification.setStatus(NotificationStatus.FAILED);
throw new NotificationException("站内信发送失败", e);
}
}
@Override
public boolean supports(NotificationType type) {
return type == NotificationType.SYSTEM;
}
}
// 推送通知
public class PushNotifier implements Notifier {
private static final Logger logger = LoggerFactory.getLogger(PushNotifier.class);
private PushService pushService;
public PushNotifier(PushService pushService) {
this.pushService = pushService;
}
@Override
public void send(Notification notification) {
try {
for (String receiver : notification.getReceivers()) {
PushRequest request = new PushRequest();
request.setUserId(receiver);
request.setTitle(notification.getTitle());
request.setBody(notification.getContent());
pushService.push(request);
}
notification.setStatus(NotificationStatus.SENT);
notification.setSendTime(LocalDateTime.now());
logger.info("推送通知发送成功: {}", notification.getId());
} catch (Exception e) {
logger.error("推送通知发送失败: {}", notification.getId(), e);
notification.setStatus(NotificationStatus.FAILED);
throw new NotificationException("推送发送失败", e);
}
}
@Override
public boolean supports(NotificationType type) {
return type == NotificationType.PUSH;
}
}
通知管理器
@Service
public class NotificationManager {
private static final Logger logger = LoggerFactory.getLogger(NotificationManager.class);
private List<Notifier> notifiers;
private NotificationStrategy strategy;
private NotificationRepository repository;
private ExecutorService executorService;
private RetryPolicy retryPolicy;
@Autowired
public NotificationManager(List<Notifier> notifiers,
NotificationStrategy strategy,
NotificationRepository repository) {
this.notifiers = notifiers;
this.strategy = strategy;
this.repository = repository;
this.executorService = Executors.newFixedThreadPool(10);
this.retryPolicy = new SimpleRetryPolicy(3, 1000);
}
// 发送通知(异步)
public CompletableFuture<Notification> sendAsync(Notification notification) {
return CompletableFuture.supplyAsync(() -> {
try {
send(notification);
return notification;
} catch (Exception e) {
logger.error("异步通知发送失败: {}", notification.getId(), e);
throw new CompletionException(e);
}
}, executorService);
}
// 发送通知(同步)
public Notification send(Notification notification) {
List<Notifier> matchedNotifiers = strategy.select(notifiers, notification.getType());
for (Notifier notifier : matchedNotifiers) {
try {
notifier.send(notification);
repository.save(notification);
break;
} catch (Exception e) {
logger.error("通知发送异常,尝试下一个通知器", e);
notification.setRetryCount(notification.getRetryCount() + 1);
if (shouldRetry(notification)) {
retry(notification, notifier);
}
}
}
return notification;
}
// 批量发送通知
public List<Notification> sendBatch(List<Notification> notifications) {
List<CompletableFuture<Void>> futures = notifications.stream()
.map(n -> CompletableFuture.runAsync(() -> send(n), executorService))
.collect(Collectors.toList());
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
return notifications;
}
// 重试机制
private void retry(Notification notification, Notifier notifier) {
logger.info("重试发送通知: {},第{}次尝试", notification.getId(), notification.getRetryCount());
int attempt = 1;
while (attempt <= retryPolicy.getMaxRetries()) {
try {
Thread.sleep(retryPolicy.getBackoffMillis() * attempt);
notifier.send(notification);
notification.setStatus(NotificationStatus.SENT);
repository.save(notification);
return;
} catch (Exception e) {
logger.error("第{}次重试失败", attempt, e);
attempt++;
}
}
notification.setStatus(NotificationStatus.FAILED);
repository.save(notification);
}
private boolean shouldRetry(Notification notification) {
return notification.getRetryCount() < retryPolicy.getMaxRetries();
// 关闭资源
public void shutdown() {
executorService.shutdown();
}
}
策略模式实现
// 通知策略接口
public interface NotificationStrategy {
List<Notifier> select(List<Notifier> notifiers, NotificationType type);
}
// 单渠道策略
public class SingleChannelStrategy implements NotificationStrategy {
@Override
public List<Notifier> select(List<Notifier> notifiers, NotificationType type) {
return notifiers.stream()
.filter(n -> n.supports(type))
.limit(1)
.collect(Collectors.toList());
}
}
// 多渠道策略
public class MultiChannelStrategy implements NotificationStrategy {
@Override
public List<Notifier> select(List<Notifier> notifiers, NotificationType type) {
return notifiers.stream()
.filter(n -> n.supports(type))
.collect(Collectors.toList());
}
}
// 备用策略
public class FallbackStrategy implements NotificationStrategy {
@Override
public List<Notifier> select(List<Notifier> notifiers, NotificationType type) {
List<Notifier> matched = notifiers.stream()
.filter(n -> n.supports(type))
.collect(Collectors.toList());
if (matched.isEmpty()) {
// 备选所有通知器
return notifiers;
}
return matched;
}
}
重试策略
public class RetryPolicy {
private int maxRetries;
private long backoffMillis;
public RetryPolicy(int maxRetries, long backoffMillis) {
this.maxRetries = maxRetries;
this.backoffMillis = backoffMillis;
}
public int getMaxRetries() { return maxRetries; }
public long getBackoffMillis() { return backoffMillis; }
}
public class SimpleRetryPolicy extends RetryPolicy {
public SimpleRetryPolicy(int maxRetries, long backoffMillis) {
super(maxRetries, backoffMillis);
}
}
通知服务接口
public interface NotificationService {
void sendEmail(String to, String subject, String content);
void sendSms(String phone, String content);
void sendPush(String userId, String title, String content);
void sendSystemMessage(String userId, String title, String content);
}
@Service
public class NotificationServiceImpl implements NotificationService {
private NotificationManager notificationManager;
private ObjectMapper objectMapper;
@Autowired
public NotificationServiceImpl(NotificationManager notificationManager,
ObjectMapper objectMapper) {
this.notificationManager = notificationManager;
this.objectMapper = objectMapper;
}
@Override
public void sendEmail(String to, String subject, String content) {
Notification email = new Notification.Builder()
.id(UUID.randomUUID().toString())
.title(subject)
.content(content)
.receivers(Collections.singletonList(to))
.type(NotificationType.EMAIL)
.build();
notificationManager.sendAsync(email);
}
@Override
public void sendSms(String phone, String content) {
Notification sms = new Notification.Builder()
.id(UUID.randomUUID().toString())
.title("")
.content(content)
.receivers(Collections.singletonList(phone))
.type(NotificationType.SMS)
.build();
notificationManager.sendAsync(sms);
}
@Override
public void sendPush(String userId, String title, String content) {
Notification push = new Notification.Builder()
.id(UUID.randomUUID().toString())
.title(title)
.content(content)
.receivers(Collections.singletonList(userId))
.type(NotificationType.PUSH)
.build();
notificationManager.sendAsync(push);
}
@Override
public void sendSystemMessage(String userId, String title, String content) {
Notification systemMsg = new Notification.Builder()
.id(UUID.randomUUID().toString())
.title(title)
.content(content)
.receivers(Collections.singletonList(userId))
.type(NotificationType.SYSTEM)
.build();
notificationManager.sendAsync(systemMsg);
}
}
配置类
@Configuration
@EnableAsync
public class NotificationConfig {
@Bean
public NotificationStrategy notificationStrategy() {
return new MultiChannelStrategy(); // 或者使用其他策略
}
@Bean
public NotificationManager notificationManager(
List<Notifier> notifiers,
NotificationStrategy strategy,
NotificationRepository repository) {
return new NotificationManager(notifiers, strategy, repository);
}
@Bean
public EmailNotifier emailNotifier(JavaMailSender mailSender,
TemplateEngine templateEngine) {
return new EmailNotifier(mailSender, templateEngine);
}
@Bean
public SmsNotifier smsNotifier(SmsService smsService) {
return new SmsNotifier(smsService, "SMS_TEMPLATE_ID");
}
@Bean
public SystemNotifier systemNotifier(UserMessageRepository repository) {
return new SystemNotifier(repository);
}
@Bean
public PushNotifier pushNotifier(PushService pushService) {
return new PushNotifier(pushService);
}
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
}
异步处理组件
@Component
public class AsyncNotificationProcessor {
private static final Logger logger = LoggerFactory.getLogger(AsyncNotificationProcessor.class);
@Autowired
private NotificationManager notificationManager;
@Async("notificationExecutor")
public CompletableFuture<Notification> processAsync(Notification notification) {
return notificationManager.sendAsync(notification);
}
@Bean(name = "notificationExecutor")
public Executor notificationExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("notification-");
executor.initialize();
return executor;
}
}
监控和记录
@Component
public class NotificationMonitor {
private static final Logger logger = LoggerFactory.getLogger(NotificationMonitor.class);
private Map<String, Long> notificationCount = new ConcurrentHashMap<>();
private Map<String, Long> notificationFailures = new ConcurrentHashMap<>();
public void recordSuccess(Notification notification) {
String type = notification.getType().name();
notificationCount.merge(type, 1L, Long::sum);
logger.info("Notification success: {}, type: {}, cost: {}ms",
notification.getId(),
notification.getType(),
System.currentTimeMillis() - notification.getCreateTime().getNano() / 1_000_000);
}
public void recordFailure(Notification notification) {
String type = notification.getType().name();
notificationFailures.merge(type, 1L, Long::sum);
logger.warn("Notification failure: {}, type: {}",
notification.getId(),
notification.getType());
}
public Map<String, Long> getNotificationStats() {
Map<String, Long> stats = new HashMap<>();
stats.putAll(notificationCount);
stats.put("failures", notificationFailures.values().stream().mapToLong(Long::longValue).sum());
return stats;
}
}
使用示例
@RestController
@RequestMapping("/api/notifications")
public class NotificationController {
@Autowired
private NotificationService notificationService;
@Autowired
private AsyncNotificationProcessor asyncProcessor;
// 发送邮件通知
@PostMapping("/email")
public ResponseEntity<?> sendEmail(@RequestBody EmailRequest request) {
notificationService.sendEmail(
request.getTo(),
request.getSubject(),
request.getContent()
);
return ResponseEntity.ok().body("邮件通知发送成功");
}
// 发送短信通知
@PostMapping("/sms")
public ResponseEntity<?> sendSms(@RequestBody SmsRequest request) {
notificationService.sendSms(request.getPhone(), request.getContent());
return ResponseEntity.ok().body("短信通知发送成功");
}
// 发送推送通知
@PostMapping("/push")
public ResponseEntity<?> sendPush(@RequestBody PushRequest request) {
notificationService.sendPush(
request.getUserId(),
request.getTitle(),
request.getContent()
);
return ResponseEntity.ok().body("推送通知发送成功");
}
// 批量发送
@PostMapping("/batch")
public ResponseEntity<?> sendBatch(@RequestBody BatchNotificationRequest request) {
List<Notification> notifications = request.getNotifications();
notificationManager.sendBatch(notifications);
return ResponseEntity.ok().body("批量通知发送完成");
}
// 获取通知统计
@GetMapping("/stats")
public ResponseEntity<Map<String, Long>> getStats() {
return ResponseEntity.ok(notificationMonitor.getNotificationStats());
}
}
// 请求DTO
public class EmailRequest {
private String to;
private String subject;
private String content;
// getters and setters...
}
public class SmsRequest {
private String phone;
private String content;
// getters and setters...
}
public class PushRequest {
private String userId;
private String title;
private String content;
// getters and setters...
}
public class BatchNotificationRequest {
private List<Notification> notifications;
// getters and setters...
}
异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(NotificationException.class)
public ResponseEntity<ErrorResponse> handleNotificationException(NotificationException e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse(e.getMessage(), System.currentTimeMillis()));
}
@ExceptionHandler(ValidationException.class)
public ResponseEntity<ErrorResponse> handleValidationException(ValidationException e) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(new ErrorResponse(e.getMessage(), System.currentTimeMillis()));
}
}
public class NotificationException extends RuntimeException {
public NotificationException(String message) {
super(message);
}
public NotificationException(String message, Throwable cause) {
super(message, cause);
}
}
public class ErrorResponse {
private String message;
private long timestamp;
public ErrorResponse(String message, long timestamp) {
this.message = message;
this.timestamp = timestamp;
}
// getters and setters...
}
主要特性:
- 策略模式:灵活选择通知渠道
- 建造者模式:简化对象创建
- 异步处理:使用CompletableFuture和线程池
- 重试机制:自动重试失败的通知
- 监控统计:记录通知发送情况
- 多渠道支持:邮件、短信、推送、站内信
- 可扩展性:易于添加新的通知方式
这个案例展示了如何构建一个健壮、可扩展的通知系统,适合各种实际应用场景。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播