我有两个托管 bean,它们都有一个@ApplicationScope
注释:
存储.java:
@ManagedBean(eager = true)
@ApplicationScoped
public class Storage {
private static final Logger LOGGER = LoggerFactory.getLogger(Storage.class);
private List<Sheet> sheets = new ArrayList<Sheet>();
public List<Sheet> getSheets() {
return sheets;
}
public Sheet load(String id) {
// ...
}
public void storeSheet(Sheet sheet) {
sheets.add(sheet);
LOGGER.trace(""+this.hashCode()+" Stored sheet: "+sheet);
}
public void delete(Sheet s) {
sheets.remove(s);
LOGGER.trace(""+this.hashCode()+" Removed sheet: "+s);
}
}
StorageInitializer.java:
@ManagedBean(eager = true)
@ApplicationScoped
public class StorageInitializer {
@ManagedProperty(value = "#{storage}")
private Storage storage;
@PostConstruct
public void init() {
int nofSheets = 10;
int min = 20;
int max = 200;
for (int i=0; i<nofSheets; i++) {
storage.storeSheet(new Sheet(
"Sheet "+i,
ThreadLocalRandom.current().nextInt(min, max),
ThreadLocalRandom.current().nextInt(min, max)));
}
}
public void setStorage(Storage storage) {
this.storage = storage;
}
}
应用程序启动时,StorageInitializer
应将 10 个实例写入存储。其他 bean@RequestScoped
可以访问存储并使工作表可见。他们都有一个
@ManagedProperty(value = "#{storage}")
private Storage storage;
访问Storage
bean。
通过记录哈希,我可以看到有时会得到两个Storage
bean 实例。第一个由 初始化StorageInitializer
。第二个被@RequestScoped
bean 使用并且是空的。
为了解决这个问题,这看起来像是一个竞争条件或计时问题。StorageInitializer.ini()
如果我在一切工作中设置一个断点就可以了。
有任何想法吗?