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

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.

主站蜘蛛池模板: 托里县| 松溪县| 宣武区| 乐东| 勐海县| 依兰县| 郓城县| 福海县| 深州市| 杨浦区| 方城县| 醴陵市| 新乐市| 如东县| 偏关县| 临邑县| 南阳市| 上饶市| 上饶市| 法库县| 阿克苏市| 嘉峪关市| 两当县| 罗江县| 博爱县| 湘乡市| 锡林郭勒盟| 宁阳县| 栾川县| 阿瓦提县| 阳山县| 宁波市| 新竹市| 金阳县| 新巴尔虎左旗| 富裕县| 伊通| 巴东县| 白山市| 自治县| 溆浦县|