简体   繁体   中英

CDI injection styles

I read that I can inject beans in 3 different ways:

  • as field

     public class Checkout { private @Inject ShoppingCart cart; } 
  • in bean constructor

     public class Checkout { private final ShoppingCart cart; @Inject public Checkout(ShoppingCart cart) { this.cart = cart; } } 
  • in an initializer

     public class Checkout { private ShoppingCart cart; @Inject void setShoppingCart(ShoppingCart cart) { this.cart = cart; } } 

I have always used the first style and I do not see when and why to use the other two. I found a reason for using constructor injection here , when it said that it lets the class to be immutable .

Could anyone please show me useful examples of those injection styles?

The first one is short and simple. Any particular CDI-powered application would be an example.

The second one comes in handy when you methods operate with objects whose types match injected fields' ones. An example would be:

public class Garage {
    private final Car expected;
    private final List<Car> cars = new LinkedList<>();

    @Inject
    public Garage(@CarEtalon Car expected) { 
        this.expected = expected;
    }

    public void add(Collection<Car> toAdd) {
        Car expectsCheck = null;
        for (Iterator<Car> i = toAdd.iterator(); i.hasNext(); ) {
            // Due to an autocomplete issue, you've made a typo...
            expected = iterator.next();
            // and your class could've been broken by a simple typo,
            // but since our logical data model is reflected in code
            // by using 'final' keyword, compiler will stop us here.
            if (expected.matches(expectsCheck)) {
                cars.add(expectsCheck);
            }
        }
    }
}

This example is quite synthetic, but it reflects the idea quite well. POJOs adaptation (with XML descriptors) may utilize such kind of instantiation as constructor-based initialization is a lot more popular in SE world.

The latter case is quite rare. Mutable objects with mutable field to be injected are something strange, but it might come in handy. For example:

  1. Such an injection gets used for Stateful and SessionScoped beans sometimes to provide sensible defaults for their writable properties.
  2. This case is also used when object needs to be unittested and has a lot of dependencies (JSF backing beans may be a from-the-wild example). Constructor-based injection of 10 beans may end-up in writing tons of boilerplate code while setter-based one may be a reasonable compromise.
  3. POJOs adaptation for managed environment may end-up in setter-based injection if POJO has no suitable constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM