问题
Is constructor injection supported in GlassFish 3.1's implementation of CDI for managed beans? I have a @Singleton
EJB into which I want to inject another managed bean (contained in the same EJB module) using constructor injection. Field injection does work. But with constructor injection I get a NullPointerException
from AbstractSingletonContainer
.
This does work:
@Singleton
public class FooBean implements Foo {
@Inject private BarBean bar;
}
This does not work:
@Singleton
public class FooBean implements Foo {
private final BarBean bar;
@Inject
public FooBean(BarBean bar) {
this.bar = bar;
}
}
回答1:
CDI does support direct field injection, initializer method parameter injection and constructor parameter injection. From the CDI 1.0 specification:
3.7. Bean constructors
When the container instantiates a bean class, it calls the bean constructor. The bean constructor is a constructor of the bean class.
The application may call bean constructors directly. However, if the application directly instantiates the bean, no parameters are passed to the constructor by the container; the returned object is not bound to any context; no dependencies are injected by the container; and the lifecycle of the new instance is not managed by the container.
3.7.1. Declaring a bean constructor
The bean constructor may be identified by annotating the constructor
@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() {} ... }
If a bean class does not explicitly declare a constructor using
@Inject
, the constructor that accepts no parameters is the bean constructor.If a bean class has more than one constructor annotated
@Inject
, the container automatically detects the problem and treats it as a definition error.If a bean constructor has a parameter annotated
@Disposes
, or@Observes
, the container automatically detects the problem and treats it as a definition error.A bean constructor may have any number of parameters. All parameters of a bean constructor are injection points.
I wonder if your problem could be related to WELD-141 though.
References
- CDI 1.0 specification
- Section 3.7. "Bean constructors"
- Weld Documentation
- 4.1. Injection points
回答2:
Constructor injection is supported in GlassFish 3.x but you must provide a default constructor anyway to satisfy EJB specs.
This will work:
@Singleton
public class FooBean implements Foo {
private final BarBean bar;
public FooBean() {
this.bar = null;
}
@Inject
public FooBean(BarBean bar) {
this.bar = bar;
}
}
but Glassfish (this part is container dependant) will call the default constructor before the Injected one.
来源:https://stackoverflow.com/questions/3541448/glassfish-cdi-and-constructor-injection