带有@Produces注释但无范围的方法的行为

时间:2017-03-15 12:43:49

标签: java java-ee ejb cdi java-ee-7

我有一个带有@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创建的频率是多少?我怀疑每次访问,是否正确?有关于此的文件吗?

2 个答案:

答案 0 :(得分:7)

来自CDI(1.2)规范

  

当通过注释bean类或没有显式声明作用域时   生产者方法或字段bean的范围是默认的。

     

未明确声明范围的bean的默认范围   取决于其声明的陈规定型观念:

     

•如果bean没有声明任何具有声明默认值的构造型   范围,bean的默认范围是@Dependent。

     

•如果bean声明了所有已声明的构造型   默认范围具有相同的默认范围,然后该范围是   bean的默认范围。

     

•如果bean声明了两种不同的构造型   声明不同的默认范围,然后没有默认范围和   bean必须显式声明一个范围。如果没有明确说明   声明一个范围,容器自动检测问题和   将其视为定义错误。

     

如果bean显式声明了作用域,则声明了任何默认作用域   刻板印象被忽略了。

您可以从此处http://www.cdi-spec.org/download/

下载规范

答案 1 :(得分:3)

由于您没有定义任何范围,因此您的生成的bean将通过defaut @Dependent

这意味着生成的bean的生命周期将是注入它的bean的生命周期。

所以如果你有以下生产者:

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

如果您在@ApplicationScoped Pie Bean中注入Apple:

@ApplicationScoped
public class Pie {

    @Inject
    private Apple apple;
}

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

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