1

我正在编写一个简单的 JSF 应用程序来转换货币。

有一个Rates保存数据的Currencies类,用于管理请求的Manage类和用于添加新货币的类。我的问题是:我希望将货币作为 Rates 类的属性保留,因此我使用@ApplicationScoped. 但是我可以看到Rates 每次请求都会重新初始化。这是我的代码Rates

@ManagedBean
@ApplicationScoped
public class Rates {

private Map<String, Double> rates = new HashMap<String, Double>();
private Set<String> currencies = new HashSet<String>(){
    {
        System.out.println("HashSet initializing");
    }
};
private List<String> list = new ArrayList<String>(Arrays.asList("Filip", "Kasia"));

public List<String> getList() {
    return list;
}

public void setList(List<String> list) {
    this.list = list;
}

public Rates() {
    rates.put("PLN_EUR", 0.25);
    rates.put("EUR_PLN", 4.0);
    currencies.add("PLN");
    currencies.add("EUR");
}

public Map<String, Double> getRates() {
    return rates;
}

public void setRates(Map<String, Double> rates) {
    this.rates = rates;
}

public Set<String> getCurrencies() {
    return currencies;
}

public void setCurrencies(Set<String> currencies) {
    this.currencies = currencies;
}

public void addRate(String firstCurrency, String secondCurrency){
    if(rates.containsKey(firstCurrency + "_" + secondCurrency))
        return;
    double rate = (double)(Math.random()*10);
    rates.put(firstCurrency + "_" + secondCurrency, rate);
    rates.put(secondCurrency + "_" + firstCurrency, 1 / rate);
    currencies.add(firstCurrency);
    currencies.add(secondCurrency);
    System.out.println(currencies);

}

public double getRate(String currencies){
    return rates.get(currencies);
}
}

以下是它的注入方式:

@ManagedBean
public class Manage {
private String firstCurrency;
private String secondCurrency;
private @Inject Rates rates;

public String getSecondCurrency() {
    return secondCurrency;
}

public void setSecondCurrency(String secondCurrency) {
    this.secondCurrency = secondCurrency;
}

public String getFirstCurrency() {
    return firstCurrency;
}

public void setFirstCurrency(String firstCurrency) {
    this.firstCurrency = firstCurrency;
}

public void addCurrencies(){
    rates.addRate(firstCurrency, secondCurrency);
}


}

正如您所看到的,我为 Rates 的属性添加了实例初始化程序,设置currencies 并且每个请求都会打印出文本“HashSet initializing”。

4

1 回答 1

3

@Inject仅注入 CDI 托管 bean。

@ManagedBean声明 JSF 托管 bean 而不是 CDI 托管 bean。

Rates类改为 CDI 托管 bean。

import javax.inject.Named;
import javax.enterprise.context.ApplicationScoped;

@Named
@ApplicationScoped
public class Rates {}

应该注意的是,一般建议是停止使用 JSF 托管 bean 设施并专门使用 CDI 托管 bean 设施。因此,如果您也将所有其他 JSF 托管 bean 设为 CDI 托管 bean,那就更好了。这就是为什么我不建议@Inject用它的 JSF 等价物替换@ManagedProperty(这也可以)。

至于托管 bean 初始化,您不应该在类/实例级别进行,而是在带@PostConstruct注释的方法中执行任务。

private Map<String, Double> rates;
private Set<String> currencies;
private List<String> list;

@PostConstruct
public void init() {
    rates = new HashMap<>();
    currencies = new HashSet<>();
    list = new ArrayList<>(Arrays.asList("Filip", "Kasia"));
}

这在 CDI 中尤为重要,因为它基于类创建和注入代理,因此类可能会在您不期望的时候被实例化。

也可以看看:

于 2016-04-10T14:49:40.767 回答