我有一个关于在CDI托管的JSF bean(RequestScoped)中注入类的问题,以及这些注入的类在RequestScope期间是否是线程安全的。
最好先显示示例代码:
----------------- JSF Bean,使用CDI ------------------
import javax.enterprise.context.RequestScoped;
...
@Named
@RequestScoped
public class DemoBean {
@Inject
LocalService localService;
@PostConstruct
public void init() {
localService.reloadCache();
}
public String getName() {
return localService.getName();
}
public String getAge() {
return localService.getAge();
}
}
-----------------服务,使用CDI ------------------
@Named
public class LocalService {
private String name;
private String age;
public void reloadCache() {
name = null;
age = null;
name = // slow SQL on remote Service, that needs to be cached
age = // slow SQL on remote Service, that needs to be cached
}
public String getName() {
// do some work, e.g. logging
return name;
}
public String getAge() {
// do some work, e.g. logging
return age;
}
}
JSF Bean“DemoBean”使用“LocalService”类从数据库中获取数据(通过远程EJB,但这不重要)。在“LocalService”类中,我想在请求期间缓存SQL结果,原因有两个:
如果许多JSF Beans(对JSF页面的许多并发调用)同时使用它,注入的“LocalService”类如何表现?注入的“LocalService”实例是否由其他线程共享,因此不是线程安全的?
如果是这种情况,我该如何使服务线程安全?
e.g。 (在LocalService中)
Thread1: call reloadCache()
Thread1: call getName()
Thread1 is interrupted in the middle of getName() by Thread2
Thread2: call reloadCache()
Thread2 is interrupted in the middle of reloadCache() -> name is null
Thread1: continue execution of getName() and return name -> which is null at this moment -> very bad
这个例子是我的代码的一个非常简化的版本,但我希望它让我的问题可以理解
谢谢, 基督教
答案 0 :(得分:3)
未明确声明范围的CDI bean的默认范围是@Dependent
。通过the javadoc获取此注释会向您显示,在您的特定情况下,DemoBean
的每个实例都保证拥有自己的LocalService
实例。
注入到容器正在创建的对象中的bean的任何实例都绑定到新创建的对象的生命周期。
我读了这个,因为为每个新创建的DemoBean
创建了一个实例并且同时被销毁(从长远来看,这可能对你来说很昂贵)
与您的问题无关:非规范化。如果您发现自己制作了太多的跃点来获取数据,那么就可以简单而直接地解决过度加入和相关性能成本问题。但你可能已经知道了。