在CDI中,如何在注入点为bean提供范围?

时间:2016-03-30 16:20:53

标签: cdi

在CDI中,我能够注入一个具有特定范围的bean,即定义bean类的范围。但是如果我创建没有任何作用域的bean类,并且在注入点为bean提供范围,该怎么办呢?我的要求是在后一种情况下使注入时间范围成为可能。问题是注入是在dependent scope而不是所需的注释范围内进行的,除非我使用producer

例如:

案例1:

当我在类声明中声明bean的范围时,如下所示:

@ApplicationScoped
class UserDetails {
...
}

像这样注入:

@ViewScoped
class UserView {

    @Inject
    UserDetails userDetails;
    .
    .
}

它按预期工作。在应用程序范围内注入的bean在整个应用程序中可用于所有其他bean。

案例2:

但是当我在课堂声明中没有给出范围时:

class UserDetails {
...
}

并像这样注射(在注射点给出范围):

@ViewScoped
class UserView {

    @Inject @ApplicationScoped
    UserDetails userDetails;
    .
    .
}

这失败了!注入的bean没有注入application scope但是得到了dependent scope而在我的情况下View Scope

我必须创建一个Producer& Qualifier其中@Produces方法提供所需application scope的bean。我认为如果在这种情况下我必须在application scope中注入bean类 UserDetails ,那么这个生成器/限定符扩展会成为开销。

事情是, UserDetails 类是第三方jar的一部分。此类没有声明任何范围,并且是POJO。我无法更改其源代码。

基于上述讨论,我有两个问题:

  1. 为什么当有人知道要在特定范围内注入bean时,会创建没有范围定义的bean类?这种做法在设计方面是否有用?

  2. 由于我无法控制bean类的源代码,并且因为它们与任何范围无关,生成器/限定符扩展是否是在所需范围内注入此类bean的唯一好方法?

3 个答案:

答案 0 :(得分:5)

<强> 1。没有定义范围的对象 - 使用@Dependent

CDI会将对象范围视为@Dependent scope

  

从不在不同的bean之间共享依赖bean的实例   客户或不同的注射点。它完全是一个依赖   一些其他对象的对象。它是对象实例化的   属于被创建,并在它所属的对象被销毁时被销毁   破坏。

     

范围为@Dependent的Bean不需要代理对象。客户端   直接引用它的实例。

Spring IoC dev :CDI @Dependent范围类似于Spring IoC Prototype范围。

<强> 2。没有@Produces&amp;使用@Inject

CDI将为每次注入创建UserDetails的新实例(@Dependent范围)。这里没有共享数据!你不能像你那样定义范围(注射时)。

第3。使用@Produces&amp;使用@Inject

您可以控制UserDetails对象的范围(ApplicationScoped,SessionScoped或RequestScoped)

public class Producers {

     @Produces @ApplicationScoped
     public UserDetails createUserDetails() {
         // Initialize UserDetails
     }

     public void release(@Disposes UserDetails userDetails) {
         // Release userDetails if you have to
     }
}

<强> 4。另一种方法:尽可能扩展UserDetails

    @ApplicationScoped // Or @SessionScoped, @RequestScoped
    public class UserDetailsImpl extends UserDetails {
        //
    } 

如果您希望ApplicationDcoped用于UserDetails。可以使用方式3或方式4。

答案 1 :(得分:2)

范围始终在bean上定义,而不是在注入点上定义。

注入点不能改变注入bean的范围。

答案 2 :(得分:0)

我认为你可以通过在注入点附近指定@ApplicationScoped注释来注入@Dependent bean作为@New bean,但是你不能这样做。