我正在编写一个简单的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);
}
}
如您所见,我为Rate属性添加了实例初始值设定项,设置currencies
和文本&#34; HashSet初始化&#34;每次请求都会打印出来。
答案 0 :(得分: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也做得更好,那就更好了。这就是为什么我不建议用它的JSF等效@Inject
替换@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中尤其重要,因为它根据类创建并注入link,因此可以在您不期望的时候实例化类。