@Injected @ManagedBean gets reinitialized despite of @ApplicationScoped annotation

只谈情不闲聊 提交于 2019-12-08 05:11:10

问题


I am writing a simple JSF application for converting currencies.

There is a Rates class which holds the data, Currencies class for managing requests and Manage class for adding new currencies. My problem is: I want the currencies to be persisted as a property of Rates class hence my use of @ApplicationScoped. However I can see that Rates keeps getting reinitialized with every single request. Here's my code of 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);
}
}

and here's how it get's injected:

@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);
}


}

As you can see I added instance initializer for a property of Rates, set currencies and the text "HashSet initializing" is printed out with every request.


回答1:


@Inject only injects CDI managed beans.

@ManagedBean declares a JSF managed bean not a CDI managed bean.

Make the Rates class a CDI managed bean instead.

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

@Named
@ApplicationScoped
public class Rates {}

Noted should be that the general recommendation is to stop using JSF managed bean facility and exclusively use CDI managed bean facility. So it'd be better if you make all your other JSF managed beans CDI managed beans too. That's exactly why I wouldn't recommend to replace @Inject by its JSF equivalent @ManagedProperty (which would also have worked).

As to managed bean initialization, you should not do it at class/instance level, but perform the task in a @PostConstruct annotated method.

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"));
}

This is particularly important in CDI because it creates and injects proxies based on the class, so the class may be instantiated at times you don't expect.

See also:

  • Backing beans (@ManagedBean) or CDI Beans (@Named)?


来源:https://stackoverflow.com/questions/36531112/injected-managedbean-gets-reinitialized-despite-of-applicationscoped-annotati

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!