将两个@RequestScoped bean作为不同的实例注入

时间:2015-11-09 14:06:26

标签: java java-ee

我有以下情况(Java EE,CDI,jax.rs):

我有一个RequestScoped Bean,它存储在请求的实时时间中使用的一些数据:

MyHandler.java:
@RequestScoped
public class MyHandler
{
    ....
}

然后我有我的REST调用,它使用我的处理程序Bean的两个不同的实例:

MyRestCall.java:
@Stateless
public class MyRestCall
{
    @Inject
    MyHandler handlerA;

    @Inject
    MyHandler handlerB;

    ....
}

然而,发生的是, hanlderA handlerB 是同一个对象。但我想有两个不同的。我怎样才能以正确的方式实现这一目标?当然,我可以创建一个基类 Handler ,然后派生两个单独的类 HandlerA HandlerB ,并将它们作为 handlerA <注入它们/ em>和 handlerB 。但我希望以更清洁的方式。

2 个答案:

答案 0 :(得分:5)

这个bean是请求范围,因此在请求生命周期中,应该只有一个这样的bean通过所有处理提供服务。你不应期望得到一个新的。

具有此类行为的范围是@Dependent范围。你有没有考虑过将它用于那个bean?每次注入它都会产生新的bean,所以它看起来更像是一个更好的解决方案。当然,在其他地方你使用相同的bean会注入新的。

答案 1 :(得分:2)

尝试对Instance使用@New注释:

@Inject
@New(MyHandler.class)
Instance<MyHandler> handlerInstanceA;

@Inject
@New(MyHandler.class)
Instance<MyHandler> handlerInstanceB;

然后使用以下方式获取您的实例:

MyHandler handlerA = handlerInstanceA.get();
MyHandler handlerB = handlerInstanceB.get();

更新

documentation表示CDI 1.1中已弃用@New,而应使用@Dependent范围:

  

New限定符在CDI 1.1中已弃用。鼓励CDI应用程序注入Dependent范围的bean。

所以使用:

@Inject
MyHandler handlerA;

@Inject
MyHandler handlerB;

由于@Dependent是默认的CDI范围,请将MyHandler留下注释,并使用@Dependent对其进行注释:

@Dependent
public class MyHandler {...}

根据@Dependent documentation

  

使用范围@Dependent声明的Bean与具有其他内置范围类型的bean的行为不同。当bean声明具有范围@Dependent时:

     

•在多个注入点之间不共享注入的bean实例   •注入到容器正在创建的对象中的bean的任何实例都绑定到新创建的对象的生命周期。