【问题标题】:GlassFish, CDI and constructor injectionGlassFish、CDI 和构造函数注入
【发布时间】:2011-04-02 06:29:53
【问题描述】:

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

这确实有效:

@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;
    }

}

【问题讨论】:

  • 什么版本的 glassfish?如果这不是 3.0.1,请尝试一下。
  • 我想明白了。该示例实际上正在运行。只有当 glassfish 启动时耳朵已经展开时,它才会崩溃。重新部署后就可以工作了。对我来说似乎是一个 GlassFish 错误。

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


【解决方案1】:

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 之前调用默认构造函数。

【讨论】:

  • 只要变量barfinal,就不会编译。
【解决方案2】:

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 声明一个构造函数, 接受 no 的构造函数 parameters 是 bean 构造函数。

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

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

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

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

参考文献

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    相关资源
    最近更新 更多