[//]: # " "
[//]: # " Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved. "
[//]: # " Copyright (c) 2021 Payara Services Ltd. "
[//]: # " "
[//]: # " This program and the accompanying materials are made available under the "
[//]: # " terms of the Eclipse Public License v. 2.0, which is available at "
[//]: # " http://www.eclipse.org/legal/epl-2.0. "
[//]: # " "
[//]: # " This Source Code may also be made available under the following Secondary "
[//]: # " Licenses when the conditions for such availability set forth in the "
[//]: # " Eclipse Public License v. 2.0 are satisfied: GNU General Public License, "
[//]: # " version 2 with the GNU Classpath Exception, which is available at "
[//]: # " https://www.gnu.org/software/classpath/license.html. "
[//]: # " "
[//]: # " SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 "
[//]: # " "

* TOC
{:toc}

# Introduction to GlassFish HK2

This page describes the GlassFish HK2 3.0 API, which is based on Jakarta Dependency Injection (DI) standard annotations.
Also, Habitat has been replaced with a new interface called [ServiceLocator][servicelocator].

GlassFish HK2 is a declarative framework for services using annotations like [Contract][contract] and [Service][service].
This page is intended to show simple usages of GlassFish HK2 mainly using the standard Jakarta DI API.

For information about using the GlassFish HK2 programmatic API see [this page][api-overview].
For information about GlassFish HK2 extensibility options see [this page][extensibility]
For information about Jakarta DI see [this site][jakartadi].

This page assumes that you are using the GlassFish HK2 provided ability to automatically find and
register services in an GlassFish HK2 registry.  For more information on how to control what services
are automatically bound to what registries see TBD.

## Getting Started

In order to mark a concrete implementation class as one that should be available 
as a service you annotate your class with [@Service][service].
 
```java
@Service
public class Foo {
}
```

By default Foo will be advertised as itself and by any interfaces that are marked with [@Contract][contract].
Lets make Foo an interface that is a Contract and create an implementation of Foo:
 
```java
@Contract
public interface Foo {
}

@Service
public class FooImpl implements Foo {
}
```

The FooImpl class will be placed into the registry advertised under both FooImpl and Foo.
 
## Named Services
 
In order to differentiate different implementations of the same interface you can name your services.
Here is an example of a class that implements a contract and has two implementations, both named differently:
 
```java
@Contract
public interface Book {
}

@Service @Named
public class MobyDick implements Book {
}

@Service @Named
public class ParadiseLost implements Book {
}
```

The two classes, MobyDick and ParadiseLost, will be added to the service registry with the names
"MobyDick" and "ParadiseLost".  If you use the [Named][named]
qualifier without specifying a name then the name you get is the class name without the package.
 
## Qualified Services

Services can also be qualified with annotations called qualifiers.  Qualifiers are annotations that are themselves
annotated with [@Qualifier][qualifier].  Here is an
example contract with three implementations:
 
```java
@Contract
public interface Color {
}

@Service @Blue
public class BlueColor implements Color {
}

@Service @Red
public class RedColor implements Color {
}

@Service @Yellow
public class YellowColor implements Color {
}
```

The Blue annotation is defined like this:

```java
@Qualifier
@Retention(RUNTIME)
@Target( { TYPE, METHOD, FIELD, PARAMETER })
public @interface Blue {
}
```

It is an exercise left up to the reader to implement the Red and Yellow annotations.
 
## Basic Injection

Lets make our example a little more interesting by injecting a book into Foo.  This is done using the
Jakarta DI standard [Inject][inject] annotation:
 
```java
@Service
public class FooImpl implements Foo {
  @Inject
  private Book book;
  
  ...
}
```

Upon construction the book field will be filled in by GlassFish HK2.  You can also inject into the constructor of FooImpl, or
use an initializer method.  In both of those cases the constructor or method must be annotated with
[@Inject][inject] in order to tell GlassFish HK2 which is the proper constructor or method to call.

Here is FooImpl implemented with constructor injection:
 
```java
@Service
public class FooImpl implements Foo {
  private final Book book;
  
  @Inject
  public FooImpl(Book book) {
      // constructor injected!
      this.book = book;
  }
}
```

Here is FooImpl implemented with initializer method injection:
 
```java
@Service
public class FooImpl implements Foo {
  private Book book;
  
  @Inject
  public void setBook(Book book) {
      // initializer method injected!
      this.book = book;
  }
}
```

In all three of the above cases (field injected, constructor injected or initializer method injected) the injection will occur
prior to the postConstruct method of FooImpl.  In this example we use the injected book in the postConstruct method:
 
```java
@Service
public class FooImpl implements Foo {
  @Inject
  private Book book;
  
  @PostConstruct
  private void postConstruct() {
      book.doSomething();
  }
}
```

## Injection by name

The astute observer of our example will have noticed that when injecting a Book into FooImpl that we never selected which book we wanted.
That can be fixed by using the [Named][named] qualifier at the point of injection.  Lets fix the example by injecting both of the Books we defined earlier:
 
```java
@Service
public class FooImpl implements Foo {
  @Inject @Named("MobyDick")
  private Book mobyDick;
  
  @Inject @Named("ParadiseLost")
  private Book paradiseLost;
}
```

The implementation of Book given the name "MobyDick" will be injected into the mobyDick field, and the implementation of
Book given the name "ParadiseLost" will be injected into the paradiseLost field.
 
## Injection by qualifier

Injections can also be more specifically chosen by using qualifiers.  In the previous example we created three implementations
of Color, each of which was qualified with a qualifier.  Here we create a class called ColorMixer which injects the colors
in an initializer method, which also demonstrates that an initializer method (or constructor) can take more than one
parameter:

```java
@Service
public class ColorMixer {
    private Color red;
    private Color blue;
    private Color yellow;
  
    @Inject
    private void addPrimaries(
            @Red Color red,
            @Blue Color blue,
            @Yellow Color yellow) {
      this.red = red;
      this.blue = blue;
      this.yellow = yellow;
   }
}
```

Note that the qualifiers can go on the parameters of the initializer method addPrimaries.  In the above example the RedColor,
BlueColor and YellowColor services will be injected into the proper fields of the initializer.
 
## Provider injection

There are times when your code would like finer control over when a instance of a service is created.
Anywhere that you can inject a service, you can also inject a [Provider][atinjectprovider].
When you inject a [Provider][atinjectprovider] for a service rather than
the service itself the system will potentially delay the creation of the service until the 
[get][providerget] method of the [Provider][provider] has been called.
 
Lets go back to our ColorMixer example, and inject providers (into fields this time) for our primaries.
 
```java
@Service
public class ColorMixer {
    @Inject @Red
    private Provider<Color> redProvider;
    
    @Inject @Blue
    private Provider<Color> blueProvider;
    
    @Inject @Yellow
    private Provider<Color> yellowProvider;
}
```

This service can then get the color implementations later.  In this method of ColorMixer we create purple by getting the
red and blue colors:

```java
@Service
public class ColorMixer {
    ...
    
    public Color makePurple() {
      return mix(redProvider.get(), blueProvider.get());
    }
}
```

Note that if no-one ever makes a color that involves using yellow, that the YellowColor implementation class will never
be created, since no-one ever called the [get][providerget] method of the yellowProvider field.

The value passed into any [Provider][provider] injection point will be an
instance of [IterableProvider][iterableprovider].
 
## IterableProvider injection

It is often the case that a single contract has more than one implementation.  Sometimes it is useful to get access to
all of the implementations of the contract.
This can be done by using an [IterableProvider][iterableprovider].
[IterableProvider][iterableprovider] extends [Provider][provider] and also implements [Iterable][iterable].
Anywhere a service can be injected an [IterableProvider][iterableprovider] for that service can be injected.

In this example we create a Library service that wants to be able to list all of the books it carries:

```java
@Service
public class Library {
    @Inject
    private IterableProvider<Book> allBooks;
    
    public LinkedList<Book> getAllBooks() {
        LinkedList<Book> retVal = new LinkedList<Book>();
        
        for (Book book : allBooks) {
            retVal.add(book);
        }
        
        return retVal;
    }
}
```

Since [IterableProvider][iterableprovider] implements [Iterable][iterable] 
it can be used in Java for/while loops, as demonstrated in the above example.

Another feature of the [IterableProvider][iterableprovider] is that it can
be used to further narrow down the selection criteria at run time.
In our above example we can progrommatically choose the book we are interested 
in based on a name passed into a method.  Here is how it would look:
 
```java
@Service
public class Library {
    @Inject
    private IterableProvider<Book> allBooks;
    
    public Book findBook(String name) {
        return allBooks.named(name).get();
    }
}
```

In the above example we call the [named][iterableprovidernamed] method [IterableProvider][iterableprovider]
in order to select the book with the given name.
The call to [get][providerget] then just returns the book with the given name.

## Iterable injection

[Iterable][iterable] can be used as an injection point rather than [IterableProvider][iterableprovider].  The following code will
work as expected:

```java
@Service
public class Library {
    @Inject
    private Iterable<Book> allBooks;
    
    public LinkedList<Book> getAllBooks() {
        LinkedList<Book> retVal = new LinkedList<Book>();
        
        for (Book book : allBooks) {
            retVal.add(book);
        }
        
        return retVal;
    }
}
```

The value passed into any [Iterable][iterable] injection point will be an
instance of [IterableProvider][iterableprovider].
 
## Conclusion

The majority of usages of GlassFish HK2 should use standard Jakarta DI annotations along with
[@Service][service] and [@Contract][contract].
In some cases code will also use [IterableProvider][iterableprovider] as outlined above.
In even rarer cases the code may need extremely specialized control over GlassFish HK2 by using the
programmatic API, as described [here][api-overview].

We have gone through many simple examples which have shown the basic functionality of GlassFish HK2 and JSR-330 in your
applications.  Hopefully they have provided you with knowledge about how these annotations work and how they
can be used in your own applications.

[servicelocator]: apidocs/org/glassfish/hk2/api/ServiceLocator.html
[contract]: apidocs/org/jvnet/hk2/annotations/Contract.html
[service]: apidocs/org/jvnet/hk2/annotations/Service.html
[jsr330]: http://www.jcp.org/en/jsr/detail?id=330
[jakartadi]: https://jakarta.ee/specifications/dependency-injection/
[api-overview]: ./api-overview.html
[extensibility]: ./extensibility.html
[inject]: https://jakarta.ee/specifications/platform/8/apidocs/javax/inject/Inject.html
[iterable]: http://docs.oracle.com/javase/6/docs/api/java/lang/Iterable.html
[iterableprovidernamed]: apidocs/org/glassfish/hk2/api/IterableProvider.html#named%28java.lang.String%29
[iterableprovider]: apidocs/org/glassfish/hk2/api/IterableProvider.html
[providerget]: http://javax-inject.github.io/javax-inject/api/javax/inject/Provider.html#get%28%29
[provider]: http://javax-inject.github.io/javax-inject/api/javax/inject/Provider.html
[named]: http://docs.oracle.com/javaee/6/api/javax/inject/Named.html
[qualifier]: https://jakarta.ee/specifications/platform/8/apidocs/javax/inject/Qualifier.html
[atinjectprovider]: http://javax-inject.github.io/javax-inject/api/javax/inject/Provider.html
