用 CDI @ApplicationScoped bean 替代 Singleton EJB,实现更简单的共享状态管理。
代码对比
✕ Java EE
@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();
}
}
✓ Jakarta EE 8+
@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。
更易测试
普通 CDI bean,无需 EJB 容器的单例语义。
标准 CDI
与其他 CDI 特性(拦截器、事件)无缝配合。
旧方式
@Singleton EJB
现代方式
@ApplicationScoped CDI
自 JDK
11
难度
中级
JDK 支持
Singleton EJB 与 CDI @ApplicationScoped
可用
自 Jakarta EE 8 / Java 11 起广泛可用
工作原理
Singleton EJB 捆绑了并发管理(@Lock、@ConcurrencyManagement)和启动(@Startup)。CDI @ApplicationScoped 只需一个注解,将并发策略留给开发者。
相关文档