6

GlassFish 3.1 的托管 bean 的 CDI 实现是否支持构造函数注入?我有一个@SingletonEJB,我想使用构造函数注入向其中注入另一个托管 bean(包含在同一个 EJB 模块中)。现场注入确实有效。但是通过构造函数注入,我得到了一个NullPointerExceptionfrom 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;
    }

}
4

2 回答 2

10

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

3.7. Bean 构造函数

当容器实例化一个 bean 类时,它会调用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 类有多个构造函数 annotated @Inject,容器会自动检测到问题并将其视为定义错误。

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

一个 bean 构造函数可以有任意数量的参数。bean 构造函数的所有参数都是注入点。

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

参考

  • CDI 1.0 规范
    • 第 3.7 节。“Bean 构造函数”
  • 焊接文件
于 2010-08-23T06:56:04.363 回答
4

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(这部分依赖于容器)将在 Injected 之前调用默认构造函数。

于 2013-02-17T14:15:43.463 回答