GlassFish,CDI和构造函数注入

时间:2010-08-22 12:20:23

标签: dependency-injection glassfish java-ee-6 cdi constructor-injection

GlassFish 3.1的托管bean的CDI实现是否支持构造函数注入?我有一个@Singleton EJB,我想使用构造函数注入注入另一个托管bean(包含在同一个EJB模块中)。现场注入确实有效。但是通过构造函数注入,我从NullPointerException得到AbstractSingletonContainer

这确实有效:

@Singleton
public class FooBean implements Foo {

  @Inject private BarBean bar;

}

这不起作用:

@Singleton
public class FooBean implements Foo {

    private final BarBean bar;

    @Inject
    public FooBean(BarBean bar) {
        this.bar = bar;
    }

}

2 个答案:

答案 0 :(得分:9)

CDI确实支持直接场注入,初始化方法参数注入和构造函数参数注入。从CDI 1.0规范:

  

3.7。 Bean构造函数

     

当容器实例化bean时   class,它调用 bean   构造。 bean构造函数是   bean类的构造函数。

     

应用程序可能会调用bean   直接构造者。但是,如果   应用程序直接实例化   bean,没有参数传递给   容器构造函数;该   返回的对象不绑定任何   上下文;没有依赖注入   由容器;和...的生命周期   新实例不受管理   容器

     

3.7.1。声明bean构造函数

     

可以识别bean构造函数   通过注释构造函数   @Inject

@SessionScoped
public class ShoppingCart implements Serializable {
    private User customer;

    @Inject
    public ShoppingCart(User customer) {
        this.customer = customer;
    }

    public ShoppingCart(ShoppingCart original) {
        this.customer = original.customer;
    }

    ShoppingCart() {}

    ...
}

@ConversationScoped
public class Order {
    private Product product;
    private User customer;

    @Inject
    public Order(@Selected Product product, User customer) {
        this.product = product;
        this.customer = customer;
    }

    public Order(Order original) {
        this.product = original.product;
        this.customer = original.customer;
    }

    Order() {}

    ...
}
     

如果bean类没有显式   使用@Inject声明构造函数,   不接受的构造函数   参数是bean构造函数。

     

如果bean类有多个   构造函数注释@Inject ,.   容器自动检测到   问题并将其视为定义   错误。

     

如果bean构造函数有参数   带注释的@Disposes@Observes,   容器自动检测   这个问题并将其视为一个问题   定义错误。

     

bean构造函数可以包含任何数字   参数。 a的所有参数   bean构造函数是注入点。

我想知道你的问题是否与WELD-141有关。

参考

答案 1 :(得分:3)

GlassFish 3.x支持构造函数注入,但您必须提供默认构造函数以满足EJB规范。

这将有效:

@Singleton
public class FooBean implements Foo {

    private final BarBean bar;

    public FooBean() {
      this.bar = null;
    }

    @Inject
    public FooBean(BarBean bar) {
        this.bar = bar;
    } 
}

但是Glassfish(此部分取决于容器)将在注入的之前调用默认构造函数。