来自Spring的普通老版DI我无法弄清楚如何在用CDI写作时正确选择范围。
在Spring中,默认情况下我的所有服务都有单例作用域,我认为它映射到CDI中的应用程序作用域(甚至是@Singleton)。我知道,例如登录用户信息我需要使用会话范围,例如形式参数我需要请求范围。
假设我有一个隐藏外部服务API调用的bean。这完全是无国籍的。我应该把它作为@Singleton
还是简单地应用范围?或者让它在每个请求上创建(可能是坏选项)。
向所有地方注入是否正确?在Spring中,我按new
创建数据对象。我应该在CDI中做同样的事情,还是仅仅@Inject
呢?
答案 0 :(得分:1)
你只使用CDI吗?还是Java EE 6容器?如果你有一个用于服务调用的无状态类,那么我建议使用来自EJB规范的@Stateless(所以你需要一个Java EE 6容器)它不是单例,但它不是在每个请求上创建。我认为它与会话更紧密地绑定,但由于它是无状态的,因此可以汇集和共享实例。如果您只处理CDI,我相信Singleton会更直接地匹配Spring的单例,但我建议使用ApplicationScoped,因为它提供了一个代理,使得使用它的bean的序列化更容易。
答案 1 :(得分:0)
@Service
@Scope("prototype")
public class CustomerService
{
......
}
只需将@Scope(“prototype”)注释添加到组件中即可。
答案 2 :(得分:0)
你有理由需要豆子来记住它的状态吗?如果您正在使用类似Web客户端的东西,那么这是一个更好的存储状态的地方,例如,会话范围的托管bean(假设为jsf),或者您的案例的任何等效项。在后端服务器端,你的EJB最好保持为@stateless,以便将开销降到最低,并帮助'保持简单......'范例。如果这样做,只需在你的bean上声明@Stateless。除非有理由使用单例,否则如果你想为你的服务使用Java EE容器,最好再使用无状态bean。
每个请求都没有真正重新创建无状态bean。这就是游泳池的目的。应用程序服务器随时保持现成的无状态bean供应,如果它变得繁忙,它会产生更多,如果它静止,它将清空一些。