HK2 - Dependency Injection Kernel

A light-weight and dynamic dependency injection framework

Events

The HK2 event service provides a pluggable mechanism that allows delivery of messages from service to service. Those services sending events are called publishers and those receiving events are called subscribers. A message can be any java object.

Topics

A Topic is a special HK2 service that can be injected into a service or can be looked up from a ServiceLocator. It normally is injected as a ParameterizedType, where the generic Type is the class of the event that will be published. So if there is an event class called ImportantEvent that is to be distributed to subscribers, the injection point for the Topic might look like this:

    @Inject
    Topic<ImportantEvent> importantEventTopic;

The publish method of Topic will distribute the message to the set of subscribers. In this way the subscribers and the publishers need not have any previous knowledge of each other.

A Topic may have qualifiers associated with it. These qualifiers will normally be used to further select the set of subscribers who should receive the message. In the following example only those subscribers who ask for CodeRed ImportEvent events will receive them (assuming CodeRed is a qualifier):

    @Inject @CodeRed
    Topic<ImportantEvent> importantEventTopic;

Pluggability

In order to provide maximum flexibility in terms of qualities of service between publishers and subscribers the HK2 event subsystem is pluggable. This means that when a message is published by the publish method of the Topic service it is not given directly to the subscribers. Instead there is an HK2 service called the TopicDistributionService that is responsible for distributing messages from the producer to the subscribers.

Having the TopicDistributionService be responsible for the distribution of messages allows the designers of the system to control the quality of service between the producers and the subscribers. Some of the qualities of service that can be controlled this way are security, threading and error handling. It is even possible to distribute events outside of the JVM if that is what the TopicDistributionService decides to do!

The TopicDistributionService has a method called distributeMessage which is responsible for sending events to subscribers. It takes the Topic that sent the message and the message to send. The Topic contains information concerning the Type of the Topic and all of its associated qualifiers.

HK2 provides a default implementation of TopicDistributionService which will be described in the sections below.

The Default TopicDistributionService

In order to enable the default TopicDistributionService the ServiceLocatorUtilities method enableTopicDistribution should be called:

    public void initializeEvents(ServiceLocator locator) {
        ServiceLocatorUtilities.enableTopicDistribution(locator);
    }

The default TopicDistributionService is named HK2TopicDistributionService and has a priority of 0. It is possible to enhance the behavior of the default TopicDistributionService by adding an implementation of TopicDistributionService with a higher priority and which injects the default TopicDistributionService. Then the default implementation can be delegated to by the custom enhanced TopicDistributionService. An example of how to do this is given here.

Subscribers

In the HK2 default system subscribers are found by finding methods on services that have a single parameter annotated with @SubscribeTo. Any other parameters of the method are considered to be injection points that should be satisfied by normal HK2 services. The following methods are all subscribers to ImportantEvent:

  public void importantEventSubscriber(@SubscribeTo ImportantEvent event) {
    // Do something with this important event
  }
  
  public void importantEventSubscriber(@SubscribeTo ImportantEvent event, ServiceLocator locator) {
    // Do something with this important event and with the ServiceLocator
  }
  
  public void importantEventSubscriber(ServiceLocator locator, @SubscribeTo ImportantEvent event) {
    // Do something with this important event and with the ServiceLocator
  }

All three of the above methods will be called when a Topic publish method is called with an ImportantEvent.

In the default implementation the subscribers will be called on the same thread as the caller of the Topic publish method. Any exceptions thrown by subscribers (or for other reasons such as an injection point not being available) will be given to all registered implementations of the DefaultTopicDistributionErrorService. The default TopicDistributionService will only distribute events to services whose instances were created after the ServiceLocatorUtilities method enableTopicDistribution has been called. Any subscribers on a service that is disposed or has had its associated descriptor removed will not be invoked.

Events will only be given to services that have already been created. For example an event will not cause a Singleton service that has not already been instantiated to become instantiated, even if the Singleton service is a listener to the event.

A method parameter with @SubscribeTo can also take qualifiers. A qualifier will restrict the set of messages that will be given to the subscription method. For example the following method will only get ImportantEvents from Topics that are also qualified with the CodeRed qualifier:

  public void codeRedSubscriber(@SubscribeTo @CodeRed ImportantEvent redEvent) {
    // do something with the code-red event
  }

If an injection point on a subscription method has scope PerLookup then the instance of that service will be disposed after the subscription method has returned.

Conclusion

Events can help your application have low cohesion, as subscribers and publishers need not have any relationship other than agreeing on an event Type. HK2 provides a powerful mechanism for plugging in any messaging provider to provide desired qualities of service. A default messaging provider is available which can either be replaced or enhanced if other qualities of service are required by the application.