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

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:

主站蜘蛛池模板: 萍乡市| 资溪县| 七台河市| 满洲里市| 资溪县| 鹤峰县| 尼木县| 永登县| 共和县| 榕江县| 合作市| 谢通门县| 吉木萨尔县| 禹城市| 临湘市| 凭祥市| 玉山县| 河东区| 嘉黎县| 铜陵市| 乾安县| 江达县| 泰宁县| 锡林郭勒盟| 房山区| 广宗县| 九龙县| 湖口县| 渝中区| 孟津县| 浑源县| 泸州市| 绩溪县| 通江县| 香河县| 龙口市| 台北市| 上虞市| 荔浦县| 永宁县| 化州市|