官术网_书友最值得收藏!

What is an injection point?

An injection point is identified by the @Inject annotation. Previously, we covered a nondefault constructor for a bean that was annotated with @Inject, as shown in the following code:

public class PaymentProcessor {
  private final Payment payment;

  @Inject
  public PaymentProcessor(Payment payment) {
    this.payment = payment;
  }
}

This is known as bean constructor parameter injection and there can only be one constructor annotated with @Inject in a bean.

If a single constructor that defines every bean that we need to use, and thus needs to be injected, is not favored, there are two other ways to inject into our bean:

  1. Create a bean that utilizes initializer method parameter injection, which has no restrictions on how many methods may be annotated with @Inject. If we were to change the PaymentProcessor class to use initializer method parameter injection, it would look like the following code snippet:
    public class PaymentProcessor {
      private final Payment payment;
    
      @Inject
      void setPayment(Payment payment) {
        this.payment = payment;
      }
    }
  2. Create a bean that utilizes direct field injection, which also has no restrictions on the number of fields in a bean that have @Inject present. PaymentProcessor would now be:
    public class PaymentProcessor {
      @Inject
      private Payment payment;
    }

The major advantage of field over method injection is that it doesn't require any getter or setter methods to be present on the bean to perform the injection.

Tip

To create beans that are immutable, the best approach for a bean is to use either constructor or field injection.

The first time that a bean is instantiated by the container is the point when beans that match the injection points are injected ready for use.

The order in which a bean is constructed by the container is as follows:

  1. Call the constructor of the bean to create an instance of the bean; this can either be the default constructor or one marked @Inject.
  2. All fields of the bean marked @Inject will have their values initialized.
  3. All initializer methods on the bean are called.
  4. If a @PostConstruct method is present, it is called.
Note

The order in which initializer methods are called by the container is not defined by the CDI spec. Depending on the order in which they are called is not recommended as each implementation can use a different ordering.

There are three types of injection points that don't require the presence of @Inject: producer, observer, and disposer methods.

@Produces
PaymentProcessor createProcessor(Payment payment) {
  return new PaymentProcessor(payment);
}

We'll cover observer methods as part of Chapter 7, Events.

Typesafe resolution

The CDI specification defines the process of matching a bean to an injection point as typesafe resolution. Bean type and qualifiers are the criterion used by the container to perform typesafe resolution for an application.

The process of typesafe resolution is usually performed by the container during application startup, making it possible for the container to end the startup process and warn the user if any beans have unsatisfied or unresolved ambiguous dependencies.

For a bean to be assignable to a given injection point, we need to make sure that:

  • Its bean type matches the bean type of the injection point.
  • It has all qualifiers that were specified on the injection point, and any member values of those qualifiers have the same value if the member is not annotated with @Nonbinding (we cover this in the next section). If no qualifiers are present on an injection point, @Default is assumed by the container.
    Note

    For the purpose of matching a bean type, a primitive type will match its corresponding wrapper type in java.lang and array types will match if their element types match.

The typesafe resolution process is designed in such a way that it allows more than one bean to implement the same bean type. This provides great flexibility to us by:

  • The injection point selecting a specific implementation of a bean type through one or more qualifiers
  • A deployment process selecting a specific implementation for a given deployment scenario, without application changes, by enabling or disabling an alternative through XML configuration
  • Allowing beans to be divided into separate modules

Typically, when we begin developing a new application we will only have a single bean of each bean type we define. As we develop our application it becomes common place, and often necessary, to introduce various implementations for a bean type to satisfy the requirements of different runtime scenarios.

主站蜘蛛池模板: 嘉荫县| 芜湖市| 甘南县| 萨嘎县| 澄江县| 武夷山市| 辽宁省| 明水县| 五峰| 永德县| 兴宁市| 高邮市| 枣阳市| 周至县| 叶城县| 孙吴县| 县级市| 睢宁县| 丹棱县| 方正县| 区。| 平度市| 甘孜| 洪湖市| 甘德县| 台安县| 吉安市| 昭平县| 自治县| 通许县| 烟台市| 修武县| 老河口市| 方城县| 柳江县| 敖汉旗| 绥中县| 拉萨市| 新邵县| 浦城县| 缙云县|