java.util.Observer接口和
Observable类(已过时)或自定义实现。,2. 事件监听:使用
PropertyChangeListener和
PropertyChangeSupport实现属性变更通知。,3. 消息队列:集成RabbitMQ/Kafka实现异步解耦通知。,4. Spring框架:利用
ApplicationEventPublisher发布事件,配合
@EventListener注解监听处理。,5. Java原生:通过
synchronized+
wait()/
notify()实现线程间通知。,6. 广播机制:结合Redis/ZooKeeper实现分布式通知,根据场景选择单机或分布式方案。
Java实现通知功能:全面指南与最佳实践
在当今软件系统中,通知机制扮演着至关重要的角色,无论是用户操作反馈、系统状态更新,还是关键事件提醒,通知功能都能显著提升用户体验和系统响应能力,本文将从基础到高级,深入探讨Java中实现通知的各种方法。
通知机制的核心概念
通知本质上是一种消息传递机制,用于在系统不同组件间或系统与用户间传递信息,Java中的通知实现可分为三大类:
- 观察者模式:经典的一对多依赖关系实现
- 事件驱动架构:基于发布-订阅模型的解耦设计
- 消息推送技术:面向用户的实时通知传递
经典实现:观察者模式
1 Java内置观察者接口
Java曾提供java.util.Observer和Observable类(Java 9后标记为过时):
import java.util.Observable;
import java.util.Observer;
// 被观察对象
class NewsPublisher extends Observable {
void publishNews(String news) {
setChanged();
notifyObservers(news);
}
}
// 观察者
class NewsSubscriber implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("收到新消息: " + arg);
}
}
// 使用示例
public class ObserverDemo {
public static void main(String[] args) {
NewsPublisher publisher = new NewsPublisher();
publisher.addObserver(new NewsSubscriber());
publisher.publishNews("Java 17发布LTS版本!");
}
}
注意:虽然这些类已过时,但理解其原理对学习观察者模式至关重要
2 自定义观察者模式实现
现代Java推荐自定义实现观察者模式:
import java.util.ArrayList;
import java.util.List;
interface Subscriber {
void update(String message);
}
class NewsAgency {
private final List<Subscriber> subscribers = new ArrayList<>();
public void subscribe(Subscriber s) {
subscribers.add(s);
}
public void publish(String news) {
subscribers.forEach(sub -> sub.update(news));
}
}
class MobileApp implements Subscriber {
@Override
public void update(String message) {
System.out.println("[APP通知] " + message);
}
}
事件驱动通知机制
1 自定义事件系统
import java.util.EventObject;
import java.util.ArrayList;
import java.util.List;
// 事件类
class PaymentEvent extends EventObject {
private final String message;
public PaymentEvent(Object source, String msg) {
super(source);
this.message = msg;
}
public String getMessage() {
return message;
}
}
// 监听器接口
interface PaymentListener {
void paymentReceived(PaymentEvent event);
}
// 事件发布者
class PaymentService {
private final List<PaymentListener> listeners = new ArrayList<>();
public void addListener(PaymentListener listener) {
listeners.add(listener);
}
public void processPayment(double amount) {
// 处理支付逻辑...
notifyListeners("支付成功: $" + amount);
}
private void notifyListeners(String msg) {
PaymentEvent event = new PaymentEvent(this, msg);
listeners.forEach(listener -> listener.paymentReceived(event));
}
}
// 使用示例
class EmailNotifier implements PaymentListener {
@Override
public void paymentReceived(PaymentEvent event) {
System.out.println("发送邮件: " + event.getMessage());
}
}
2 Spring框架事件机制
Spring提供了更完善的事件发布订阅模型:
import org.springframework.context.ApplicationEvent;
// 自定义事件
class OrderEvent extends ApplicationEvent {
private final String message;
public OrderEvent(Object source, String msg) {
super(source);
this.message = msg;
}
public String getMessage() {
return message;
}
}
// 事件发布者
@Service
class OrderService {
private final ApplicationEventPublisher publisher;
public OrderService(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void createOrder() {
// 创建订单逻辑...
publisher.publishEvent(new OrderEvent(this, "新订单创建"));
}
}
// 事件监听器
@Component
class OrderNotificationListener {
@EventListener
public void handleOrderEvent(OrderEvent event) {
System.out.println("处理订单事件: " + event.getMessage());
}
}
消息队列实现分布式通知
1 RabbitMQ示例
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
public class NotificationProducer {
private final static String QUEUE_NAME = "notifications";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "系统维护通知: 今晚00:00-06:00进行维护";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println("通知已发送: '" + message + "'");
}
}
}
用户级通知实现
1 电子邮件通知
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;
public class EmailSender {
public static void sendEmail(String to, String subject, String body) {
final String username = "your-email@gmail.com";
final String password = "your-password";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
Session session = Session.getInstance(props,
new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(to));
message.setSubject(subject);
message.setText(body);
Transport.send(message);
System.out.println("邮件发送成功!");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
2 WebSocket实时通知
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@ServerEndpoint("/notifications")
public class NotificationEndpoint {
private static final Set<Session> sessions =
Collections.synchronizedSet(new HashSet<>());
@OnOpen
public void onOpen(Session session) {
sessions.add(session);
}
@OnClose
public void onClose(Session session) {
sessions.remove(session);
}
public static void broadcast(String message) {
sessions.forEach(session -> {
synchronized (session) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
// 在业务逻辑中调用
public static void notifyUsers(String event) {
broadcast("{"event":"" + event + ""}");
}
}
移动推送通知
1 Firebase云消息示例
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.messaging.*;
import java.io.FileInputStream;
import java.util.Collections;
public class PushNotifier {
public static void initialize() throws Exception {
FileInputStream serviceAccount =
new FileInputStream("path/to/serviceAccountKey.json");
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.build();
FirebaseApp.initializeApp(options);
}
public static void sendPushNotification(String token, String title, String body) {
Message message = Message.builder()
.setNotification(Notification.builder()
.setTitle(title)
.setBody(body)
.build())
.setToken(token)
.build();
try {
FirebaseMessaging.getInstance().send(message);
System.out.println("推送通知已发送");
} catch (FirebaseMessagingException e) {
e.printStackTrace();
}
}
}
通知系统设计最佳实践
-
可靠性设计

- 实现消息持久化存储
- 引入重试机制
- 使用事务保证一致性
-
性能优化
- 批量发送通知
- 异步处理机制
- 负载均衡设计
-
用户体验考虑
- 允许用户设置通知偏好
- 避免过度通知
- 实现通知聚合
-
安全防护
- 验证通知接收者身份
- 防止通知内容劫持
- 实施频率限制
技术选型指南
| 需求场景 | 推荐方案 | 优势特点 |
|---|---|---|
| 简单对象间通知 | 自定义观察者模式 | 轻量级、零依赖 |
| 复杂业务系统 | Spring事件机制 | 框架集成、易于扩展 |
| 分布式系统 | RabbitMQ/Kafka | 解耦、高可用、持久化 |
| 用户邮件通知 | JavaMail API | 标准化、协议支持完善 |
| 实时界面更新 | WebSocket/Server-Sent Events | 双向通信、低延迟 |
| 移动端推送 | Firebase Cloud Messaging | 跨平台、厂商通道支持 |
Java提供了从基础到企业级的完整通知解决方案体系,选择合适方案时,需综合考虑系统复杂度、性能要求和用户体验等因素,现代系统通常采用混合模式:核心业务使用消息队列保证可靠性,实时交互采用WebSocket,而用户级通知则结合邮件和移动推送。

随着云原生和微服务架构普及,通知系统正向事件驱动架构(EDA) 演进,建议开发者关注CloudEvents规范等新兴标准,这些技术将帮助您构建更加健壮、灵活的通知系统。
引用说明:本文示例代码参考自Oracle官方文档、Spring Framework文档、RabbitMQ官方教程、JavaMail API文档和Firebase官方指南,关键技术点验证参考了《Effective Java》和《Spring in Action》等权威技术书籍。
graph TD
A[通知类型] --> B[系统内通知]
A --> C[用户通知]
A --> D[分布式通知]
B --> B1[观察者模式]
B --> B2[事件监听]
B --> B3[Spring事件]
C --> C1[邮件通知]
C --> C2[Web推送]
C --> C3[移动推送]
D --> D1[RabbitMQ]
D --> D2[Kafka]
D --> D3[Redis Pub/Sub]
B1 --> E[简单轻量]
B2 --> F[解耦设计]
B3 --> G[框架集成]
C1 --> H[异步可靠]
C2 --> I[实时交互]
C3 --> J[跨平台]
D1 --> K[企业级特性]
D2 --> L[高吞吐量]
D3 --> M[低延迟]

