GlassFish, CDI and constructor injection

10,521

Solution 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

Solution 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.

Share:
10,521

Related videos on Youtube

Toni
Author by

Toni

Updated on June 04, 2022

Comments

  • Toni
    Toni almost 2 years

    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;
        }
    
    }
    
    • Devanshu Mevada
      Devanshu Mevada over 13 years
      What version of glassfish? If this was not with 3.0.1, give it a try.
    • Toni
      Toni over 13 years
      I think figured it out. The example is actualy working. It does only crash if the ear is already deployed when glassfish starts. After redeploying it works. Seems like a GlassFish bug to me.
  • Thomas Eizinger
    Thomas Eizinger over 9 years
    This will not compile as long as the variable bar is final.

Related