Pendengar notifikasi dikelola secara internal oleh perpustakaan itu sebagai referensi lemah yang berarti Anda harus memegang referensi keras secara eksternal sehingga tidak akan menjadi sampah yang dikumpulkan. Lihat baris kelas 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));
}
}
Jika GC mengambil pendengar Anda, panggilan ke "get" pada referensi lemah akan mengembalikan null dan tidak akan menyala seperti yang terlihat dari baris 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);
}
}
}
Untuk memperbaikinya, tambahkan pendengar notifikasi Anda sebagai berikut:
/// 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);
Kasus penggunaan yang cukup aneh untuk referensi yang lemah menurut saya...