CDI豆的安全性

时间:2013-01-30 15:26:00

标签: jsf-2 scope thread-safety cdi

我有一个关于在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结果,原因有两个:

  • SQL查询的性能很差(很多连接,很多数据......)
  • JSF生命周期:我不想在每个6个JSF-Lifecycles上执行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

这个例子是我的代码的一个非常简化的版本,但我希望它让我的问题可以理解

谢谢, 基督教

1 个答案:

答案 0 :(得分:3)

未明确声明范围的CDI bean的默认范围是@Dependent。通过the javadoc获取此注释会向您显示,在您的特定情况下,DemoBean的每个实例都保证拥有自己的LocalService实例。

  

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

我读了这个,因为为每个新创建的DemoBean创建了一个实例并且同时被销毁(从长远来看,这可能对你来说很昂贵)

与您的问题无关:非规范化。如果您发现自己制作了太多的跃点来获取数据,那么就可以简单而直接地解决过度加入和相关性能成本问题。但你可能已经知道了。