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

Annotation literals

Before exploring annotation literals, let's look at @Qualifiers. For multiple implementations of a bean type, the qualifiers can help specify which type to inject with the help of qualifier annotation. These can be used to aid the container in injecting the correct type of bean, as shown here:

interface OrderProcessor { ... }

@OrderPlaced
class OrderPlacedProcessor implements OrderProcessor {...}

@OrderCancelled
class OrderCancelledProcessor implements OrderProcessor {...}

Since there is more than one implementation of OrderProcessor, we can make use of a qualifier to specify which implementation to inject. This would be used when implementing classes as well as at the injection point:

@Inject @OrderPlaced    private OrderProcessor processor;
@Inject @OrderCancelled private OrderProcessor processor;

There's an additional annotation called @Alternative, which is used to define an alternate implementation. It is disabled by default and can be activated via deployment configuration in beans.xml.

Qualifiers can also be added to the Event instance using either a qualifier annotation at the injection point of the event or by passing the qualifier to the select method of the Event interface:

@Inject @OrderPlaced  private Event<ShopOrder> placedEvent;

Here, every event fired using placedEvent would have the qualifier ShopOrder. This would invoke every observer that:

  • Has a type to which the event object ShopOrder is assignable
  • Does not have any event qualifier other than the one specified at the injection point, such as OrderPlaced

It's not difficult to realize that soon we may end up having multiple qualifiers when dealing with cases. For example, you may end up with event instances annotated with qualifiers such as OrderPlaced, OrderCancelled, OrderShipped, and so on. Apart from the verbosity that it adds to the code, this is also a challenge when you need to specify the qualifier dynamically.

CDI allows for the creation of annotation instances. CDI 1 already had support for this, but CDI 2 has brought in a more convenient method to create these using some helpers. These will reduce the amount of code required to create an annotation literal. It provides an option to subclass the AnnotationLiteral class and then pass the qualifier dynamically:

event.select(new AnnotationLiteral<OrderPlaced>() {})
.fire( shopOrder );

A point to note here is that the select method can take multiple Annotation options, thus allowing for multiple event qualifiers to be passed.

There are built-in annotation literals provided as well, as mentioned in the specification:

  • javax.enterprise.inject.Any
  • javax.enterprise.inject.Default
  • javax.enterprise.inject.New
  • javax.enterprise.inject.Specializes
  • javax.enterprise.inject.Vetoed
  • javax.enterprise.util.Nonbinding
  • javax.enterprise.context.Initialized
  • javax.enterprise.context.Destroyed
  • javax.enterprise.context.RequestScoped
  • javax.enterprise.context.SessionScoped
  • javax.enterprise.context.ApplicationScoped
  • javax.enterprise.context.Dependent
  • javax.enterprise.context.ConversationScoped
  • javax.enterprise.inject.Alternative
  • javax.enterprise.inject.Typed

Annotations that don't have any members can be instantiated using the constant named INSTANCE, available on the static nested class Literal:

RequestScoped reqScopedLiteral = RequestScoped.Literal.INSTANCE;

Annotations with members have a different approach, as they provide a static factory method for obtaining the instance:

Named literalObject = NamedLiteral.of(“beanName”); 

With all these and more, CDI provides the Java developer with a solid programming model, promoting loosely coupled communication between objects and allowing for better structuring of code.

Here are a few references:

主站蜘蛛池模板: 石台县| 平湖市| 宁国市| 临夏市| 屯门区| 平昌县| 潢川县| 柏乡县| 巴楚县| 安龙县| 湘潭县| 凤城市| 视频| 嘉峪关市| 湖口县| 望都县| 武隆县| 梨树县| 永仁县| 修水县| 靖边县| 梁山县| 湘潭县| 商洛市| 吴忠市| 开鲁县| 嘉祥县| 日喀则市| 嘉祥县| 宁明县| 和政县| 观塘区| 集贤县| 波密县| 开远市| 康马县| 封开县| 准格尔旗| 乌拉特中旗| 汝城县| 烟台市|