尽管有@ApplicationScoped批注,但仍重新初始化@Injected @ManagedBean

编程入门 行业动态 更新时间:2024-10-10 04:21:18
本文介绍了尽管有@ApplicationScoped批注,但仍重新初始化@Injected @ManagedBean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

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

I am writing a simple JSF application for converting currencies.

有一个Rates类用于保存数据,Currencies类用于管理请求,而Manage类用于添加新货币.我的问题是:我希望将货币作为Rates类的属性保留下来,因此我要使用@ApplicationScoped.但是,我看到Rates 保留了每个单独请求的重新初始化.这是我的Rates代码:

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

这是注入方式:

@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".

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.

推荐答案

@Inject仅注入CDI管理的bean.

@Inject only injects CDI managed beans.

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

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

将Rates类改为CDI托管Bean.

Make the Rates class a CDI managed bean instead.

import javax.inject.Named; import javax.enterprise.context.ApplicationScoped; @Named @ApplicationScoped public class Rates {}

应注意,一般建议是停止使用JSF托管Bean工具,而仅使用CDI托管Bean工具.因此,如果您还使所有其他JSF托管Bean也成为CDI托管Bean,那就更好了.这就是为什么我不建议用等效于JSF的@ManagedProperty代替@Inject的原因(也可以).

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).

对于托管Bean初始化,您不应在类/实例级别执行此操作,而应在带有@PostConstruct注释的方法中执行任务.

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

这在CDI中尤其重要,因为它创建并注入代理基于类,因此该类可能在您不期望的时间实例化.

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.

  • 是支持bean(@ManagedBean)还是CDI Bean(@Named)? /a>

更多推荐

尽管有@ApplicationScoped批注,但仍重新初始化@Injected @ManagedBean

本文发布于:2023-11-02 07:21:36,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1551732.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:初始化   但仍   ApplicationScoped   Injected   ManagedBean

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!