JSF正在创建应用程序范围bean的两个实例
我有两个托管bean,它们都有JSF正在创建应用程序范围bean的两个实例,jsf,managed-bean,multiple-instances,application-scope,Jsf,Managed Bean,Multiple Instances,Application Scope,我有两个托管bean,它们都有@ApplicationScope注释: Storage.java: @ManagedBean(eager = true) @ApplicationScoped public class Storage { private static final Logger LOGGER = LoggerFactory.getLogger(Storage.class); private List<Sheet> sheets = new Array
@ApplicationScope
注释:
Storage.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);
}
}
访问存储
bean
通过记录散列,我可以看到有时我会得到存储
bean的两个实例。第一个由StorageInitializer
初始化。第二个被@RequestScoped
bean使用,为空
为了满足这一要求,这看起来像是一个竞赛条件或胆小问题。如果我在StorageInitializer.ini()
中设置断点,一切正常
有什么想法吗?我对两个@ApplicationScoped bean“eager=true”也有同样的问题。复制的bean位于另一个@ApplicationScoped bean的@ManagedProperty中。我通过在拥有@ManagedProperty的bean上将eager值改为false来解决这个问题。在我的例子中,急切值并不是绝对必要的。您从javax.faces.bean.ApplicationScoped导入了什么包?如果所有这些类都处于战争状态(因此不是EAR),那么运行时类路径很可能被多个不同版本的JSF库污染。检查并清理它。您是否在
StorageInitializer.init()
和托管bean中都放置了一个sysout
,以查看首先出现的内容?如果是竞争条件,那么我们可以使用一些java.util.concurrent
structure@Johnny:JSF API首先禁止多个应用程序范围的bean,因此基于此行为的任何假设都是不正确的。您使用的是什么JSF版本?试过最新的吗?
@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;
}
}
@ManagedProperty(value = "#{storage}")
private Storage storage;