JSF正在创建ApplicationScoped bean的两个实例

时间:2016-03-23 11:07:12

标签: 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 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个实例写入存储。 @RequestScoped的其他bean可以访问商店并使工作表可见。他们都有一个

    @ManagedProperty(value = "#{storage}")
    private Storage storage;

访问Storage bean。

通过记录哈希,我可以看到我有时会获得Storage bean的两个实例。第一个由StorageInitializer初始化。第二个被@RequestScoped bean使用,并且是空的。

对我而言,这看起来像是竞争条件或timinig问题。如果我在StorageInitializer.ini()设置了一个断点,一切正常。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我遇到了两个带有&#34; eager = true&#34;的@ApplicationScoped bean的问题。重复的bean位于另一个@ApplicationScoped bean的@ManagedProperty中。我通过在拥有@ManagedProperty的bean上将eager值更改为false来解决问题。在我看来,急切的价值并非绝对必要。