没有范围注释的@Produces 方法创建的bean 的默认范围是什么?

What's the default scope for a bean created by a @Produces method without a scope annotation?

我有一个带有 @Produces 注释的方法可以创建 Apple.

当我像这样@ApplicationScoped使用它时

public class AppleProducer {
    @ApplicationScoped
    @Produces
    public Apple createApple() {
        return new Apple();
    }
}

然后 Apple 只为整个应用程序创建一次。

当我像这样@RequestScoped使用它时

public class AppleProducer {
    @RequestScoped
    @Produces
    public Apple createApple() {
        return new Apple();
    }
}

然后它会为每个请求创建。

但是如果我不指定范围呢?

public class AppleProducer {
    @Produces
    public Apple createApple() {
        return new Apple();
    }
}

Apple 多久创建一次?我怀疑每次访问是否正确?有这方面的文档吗?

@Dependent

根据“2.4.4. Default scope" from the CDI (1.2) specification:

When no scope is explicitly declared by annotating the bean class or producer method or field the scope of a bean is defaulted.

The default scope for a bean which does not explicitly declare a scope depends upon its declared stereotypes:

• If the bean does not declare any stereotype with a declared default scope, the default scope for the bean is @Dependent.

• If all stereotypes declared by the bean that have some declared default scope have the same default scope, then that scope is the default scope for the bean.

• If there are two different stereotypes declared by the bean that declare different default scopes, then there is no default scope and the bean must explicitly declare a scope. If it does not explicitly declare a scope, the container automatically detects the problem and treats it as a definition error.

If a bean explicitly declares a scope, any default scopes declared by stereotypes are ignored.

由于您没有定义任何范围,因此您生成的 bean 默认为 @Dependent

这意味着生成的bean的生命周期将是注入它的bean的生命周期(包含@Inject)。

因此,如果您有以下制作人:

public class AppleProducer {
    @Produces
    public Apple createApple() {
        return new Apple();
    }
}

如果你在 @ApplicationScoped Pie Bean 中注入苹果 :

@ApplicationScoped
public class Pie {

    @Inject
    private Apple apple;
}

然后 Apple bean 将是 @ApplicationScoped,因此只创建一次。

如果 Pie bean 是 @RequestScoped 那么 Apple bean 将在每次请求时创建。