Jsf 2 CDI豆的螺纹安全性

Jsf 2 CDI豆的螺纹安全性,jsf-2,scope,thread-safety,cdi,Jsf 2,Scope,Thread Safety,Cdi,我有一个关于在CDI管理的JSFbean(RequestScope)中注入类的问题,以及这些注入的类在RequestScope期间是否是线程安全的 也许最好先显示示例代码: -----------------JSFbean,使用CDI------------------ import javax.enterprise.context.RequestScoped; ... @Named @RequestScoped public class DemoBean { @Inject

我有一个关于在CDI管理的JSFbean(RequestScope)中注入类的问题,以及这些注入的类在RequestScope期间是否是线程安全的

也许最好先显示示例代码:

-----------------JSFbean,使用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();
    }

}
@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;
    }
}
-----------------服务,使用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();
    }

}
@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;
    }
}
JSFbean“DemoBean”使用“LocalService”类从数据库获取数据(通过远程EJB,但这在这里并不重要)。在“LocalService”类中,我希望在请求期间缓存SQL结果,原因有两个:

  • SQL查询的性能很差(多个联接、多个数据,…)
  • JSF生命周期:我不想在6个JSF生命周期中的每一个都执行SQL查询
如果许多JSFbean(对JSF页面的许多并发调用)同时使用注入的“LocalService”类,该类的行为如何?注入的“LocalService”实例是否由其他线程共享,因此不是线程安全的

如果是这种情况,如何使服务线程安全

e、 g.(本地服务中)

这个例子是我的代码的一个非常简化的版本,但我希望它能让我的问题变得易懂

谢谢,
Christian

未明确声明作用域的CDIBean的默认作用域是
@Dependent
。查看此注释将告诉您,在您的特定情况下,
DemoBean
的每个实例都保证有自己的
LocalService
实例

任何注入容器正在创建的对象的bean实例都绑定到新创建的对象的生命周期

我读这篇文章是因为为每个新创建的
DemoBean
创建了一个实例,并同时销毁了它(从长远来看,这可能会给您带来昂贵的代价)


与您的问题无关:反规范化。如果您发现自己跳得太多而无法访问数据,那么这就是解决过度加入问题和相关性能成本的简单而直接的答案。但是您可能已经知道了这一点。

我唯一要补充的是,您实际上没有在这里缓存任何内容,因为另一个bean是
@requestscope
。一旦该请求完成,该bean以及注入其中的任何依赖bean都将被销毁。查找更长的内容,例如
@ConversationScoped
@SessionScoped