Các trình nghe thông báo được thư viện đó duy trì nội bộ dưới dạng các tham chiếu yếu, nghĩa là bạn phải giữ một tham chiếu cứng bên ngoài để chúng không bị thu thập rác. Kiểm tra các dòng lớp BasicContext 642 - 655:
public void addNotificationListener(String name, String channelNameFilter, NotificationListener listener) {
name = nullToEmpty(name);
channelNameFilter = channelNameFilter != null ? channelNameFilter : ".*";
Pattern channelNameFilterPattern = Pattern.compile(channelNameFilter);
NotificationKey key = new NotificationKey(name, channelNameFilterPattern);
synchronized (notificationListeners) {
notificationListeners.put(key, new WeakReference<NotificationListener>(listener));
}
}
Nếu GC chọn người nghe của bạn, các lệnh gọi đến "get" trên tham chiếu yếu sẽ trả về giá trị rỗng và sẽ không kích hoạt như được thấy từ các dòng 690 - 710
@Override
public synchronized void reportNotification(int processId, String channelName, String payload) {
Iterator<Map.Entry<NotificationKey, WeakReference<NotificationListener>>> iter = notificationListeners.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<NotificationKey, WeakReference<NotificationListener>> entry = iter.next();
NotificationListener listener = entry.getValue().get();
if (listener == null) {
iter.remove();
}
else if (entry.getKey().channelNameFilter.matcher(channelName).matches()) {
listener.notification(processId, channelName, payload);
}
}
}
Để khắc phục điều này, hãy thêm trình nghe thông báo của bạn như sau:
/// Do not let this reference go out of scope!
PGNotificationListener listener = new PGNotificationListener() {
@Override
public void notification(int processId, String channelName, String payload) {
// interesting code
};
};
pgConnection.addNotificationListener(listener);
Theo quan điểm của tôi, khá là một trường hợp sử dụng kỳ lạ cho các tham chiếu yếu ...