Singleton EJB vs. CDI @ApplicationScoped
Замените Singleton-EJB на CDI-бины с @ApplicationScoped для более простого управления общим состоянием.
@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();
}
}
Меньше аннотационного шума
Никаких @ConcurrencyManagement, @Lock или @Startup — только одна аннотация @ApplicationScoped.
Гибкий параллелизм
Используйте блокировки java.util.concurrent или volatile для точно необходимой потокобезопасности.
Простое тестирование
Простые CDI-бины можно напрямую инстанциировать в тестах без EJB-контейнера.
Широко доступно начиная с Jakarta EE 8 / Java 11
Singleton-EJB объединяет управление параллелизмом (@Lock, @ConcurrencyManagement) и раннюю инициализацию (@Startup) в EJB-контейнере. CDI-бин с @ApplicationScoped достигает того же жизненного цикла с одним экземпляром при значительно меньших усилиях. Когда требуется управление параллелизмом, стандартные утилиты java.util.concurrent обеспечивают более тонкий контроль, чем Lock-аннотации EJB.