Singleton EJB vs CDI @ApplicationScoped
Sostituisci i Singleton EJB con bean CDI @ApplicationScoped per una gestione più semplice dello stato condiviso.
@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();
}
}
Meno rumore di annotazioni
Nessun @ConcurrencyManagement, @Lock o @Startup — solo una singola annotazione @ApplicationScoped.
Concorrenza flessibile
Usa lock java.util.concurrent o volatile per la thread-safety di cui hai esattamente bisogno.
Test facile
I semplici bean CDI possono essere istanziati direttamente nei test senza un container EJB.
Ampiamente disponibile da Jakarta EE 8 / Java 11
I Singleton EJB raggruppano la gestione della concorrenza (@Lock, @ConcurrencyManagement) e l'inizializzazione eager (@Startup) nel container EJB. Un bean CDI @ApplicationScoped ottiene lo stesso ciclo di vita a istanza singola con molta meno cerimonia. Quando è necessario il controllo della concorrenza, le utilità standard java.util.concurrent danno un controllo più granulare rispetto alle annotazioni di lock EJB.