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

use*_*640 2 cdi

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

例如:

情况1:

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

@ApplicationScoped
class UserDetails {
...
}
Run Code Online (Sandbox Code Playgroud)

并注入如下:

@ViewScoped
class UserView {

    @Inject
    UserDetails userDetails;
    .
    .
}
Run Code Online (Sandbox Code Playgroud)

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


案例2:

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

class UserDetails {
...
}
Run Code Online (Sandbox Code Playgroud)

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

@ViewScoped
class UserView {

    @Inject @ApplicationScoped
    UserDetails userDetails;
    .
    .
}
Run Code Online (Sandbox Code Playgroud)

这失败了!注入的bean没有注入application scopedependent scope反过来(View Scope在我的情况下).

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

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

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

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

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

Loc*_*Loc 5

1.没有定义范围的对象 - 使用@Dependent

CDI将对象范围视为@Dependent范围.

从不在不同客户端或不同注入点之间共享从属bean的实例.它严格来说是某个其他对象的依赖对象.当它所属的对象被创建时被实例化,并且当它所属的对象被销毁时被销毁.

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

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

2.没有@Produces并使用@Inject

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

3.使用@Produces并使用@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
     }
}
Run Code Online (Sandbox Code Playgroud)

4.另一种方法:尽可能扩展UserDetails

    @ApplicationScoped // Or @SessionScoped, @RequestScoped
    public class UserDetailsImpl extends UserDetails {
        //
    } 
Run Code Online (Sandbox Code Playgroud)

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