Singleton EJB vs. CDI @ApplicationScoped
Ersetze Singleton-EJBs durch CDI-@ApplicationScoped-Beans für eine einfachere Verwaltung von gemeinsamem Zustand.
@Singleton
@Startup
@ConcurrencyManagement(
ConcurrencyManagementType.CONTAINER)
public class ConfigCache {
private Map<String, String> cache;
@PostConstruct
public void load() {
cache = loadFromDatabase();
}
@Lock(LockType.READ)
public String get(String key) {
return cache.get(key);
}
@Lock(LockType.WRITE)
public void refresh() {
cache = loadFromDatabase();
}
}
@ApplicationScoped
public class ConfigCache {
private volatile Map<String, String> cache;
@PostConstruct
public void load() {
cache = loadFromDatabase();
}
public String get(String key) {
return cache.get(key);
}
public void refresh() {
cache = loadFromDatabase();
}
}
Weniger Annotations-Rauschen
Kein @ConcurrencyManagement, @Lock oder @Startup — nur eine einzige @ApplicationScoped-Annotation.
Flexible Nebenläufigkeit
Verwende java.util.concurrent-Locks oder volatile für genau die benötigte Thread-Sicherheit.
Einfaches Testen
Einfache CDI-Beans können in Tests direkt ohne EJB-Container instanziiert werden.
Weitgehend verfügbar seit Jakarta EE 8 / Java 11
Singleton-EJBs bündeln Concurrency-Management (@Lock, @ConcurrencyManagement) und frühzeitige Initialisierung (@Startup) im EJB-Container. Ein CDI-@ApplicationScoped-Bean erreicht denselben Single-Instance-Lebenszyklus mit wesentlich weniger Aufwand. Wenn Concurrency-Steuerung benötigt wird, bieten Standard-java.util.concurrent-Hilfsmittel feinere Kontrolle als die EJB-Lock-Annotationen.