Singleton EJB vs CDI @ApplicationScoped
Substitua Singleton EJBs por beans CDI @ApplicationScoped para um gerenciamento de estado compartilhado mais simples.
@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();
}
}
Menos ruído de anotações
Sem @ConcurrencyManagement, @Lock ou @Startup — apenas uma única anotação @ApplicationScoped.
Concorrência flexível
Use locks do java.util.concurrent ou volatile para exatamente a thread-safety que você precisa.
Testes fáceis
Beans CDI simples podem ser instanciados diretamente em testes sem um container EJB.
Amplamente disponível desde o Jakarta EE 8 / Java 11
Singleton EJBs agrupam gerenciamento de concorrência (@Lock, @ConcurrencyManagement) e inicialização antecipada (@Startup) no container EJB. Um bean CDI @ApplicationScoped alcança o mesmo ciclo de vida de instância única com muito menos cerimônia. Quando controle de concorrência é necessário, utilitários padrão do java.util.concurrent oferecem controle mais granular do que as anotações de lock do EJB.