HK2 injection in Standalone Java Application with Custom Binder

In my previous post, I gave an example of using the HK2 injection in a stand-alone application.

Please refer it in the below link.
Hk2 Injection with hk2 inhabitant file

In the above example, we have to create an HK2 inhabitant file which contains the binding information such as contract and service name and their mapping. The overhead in this approach is generating the HK2 default file. We can automate the file creation process in the maven build with hk2-inhabitant-generator plugin. But at some point, we may want to define the mapping explicitly such as using the service and contract from different libs. The hk2-inhabitant-generator may not add the contract/service mapping in the inhabitant file. Therefore, to resolve the above problem, we need to define a custom binder which contains all the bindings details.

Let’s see how can use the HK2 injection in a stand-alone application with a custom binder.

The below one is my POM file.
hk2-injection-pom

We have a standalone application which will be used for adding, deleting, updating the user details into HashMap or Google Guava Cache. We have two interfaces(UserService for service and UserDao for DAO) and three implementation classes(UserServiceImpl, UserGuavaCacheImpl and UserLocalCacheDaoImpl)

UserGuavaCacheImpl is used to do CRUD operation on Guava Chache and UserLocalCacheDaoImpl is used to do CRUD operation on HashMap.

We decide to use either Local cache or Google Guava cache based on a system property. This is a simple example to show how we can use the HK2 injection.
Refer the below image to know my project structure.

hk2-project-structure

All our interfaces should be annotated with @Contract and all the implementation classes should be annotated with @Service.

Refer below my Service implementation.
hk2-userservice

Refer my various DAO implementations below.

Refer my custom binder file which has the binding information below.

hk2-dependencybinder

In the above file, I have used “Named” annotation as we have two services for UserDao interface. If we don’t provide that then by default, the service locator injects the first available implementation.

Below is my main class which invokes the User Service to perform various CRUD operations with User Object.
hk2-Application
The below code is used to create a ServiceLocator instance and then we bind the created service locator with our custom binder.


ServiceLocator serviceLocator = ServiceLocatorFactory.getInstance().create("serviceLocator");
ServiceLocatorUtilities.bind(serviceLocator, new DependencyBinder());

We can use the ServiceLocator object for getting the Object instance like below


UserService userService = serviceLocator.getService(UserService.class, "empService");

We have two DAO implementation. We need to decide which one to use. The hk2 IterableProvider will give both the implementations classes. Therefore, I have used a system property to decide the appropriate cache implementation. Refer the below code from UserServiceImpl.


@Inject
    public UserServiceImpl(IterableProvider iterableProviders) {
        String cache = System.getProperty("CACHE");
        if (CacheDetails.GUAVA.name().equals(cache)) {
            this.userDao = iterableProviders.named("empGuavaCacheDao").get();
        }
        else if(CacheDetails.LOCAL.name().equals(cache)) {
            this.userDao = iterableProviders.named("empLocalCacheDao").get();
        }
    }

 
The output of my program is as given below,


Add user details
The user details after it has been added User: User{id='0701f22b-10b0-4d6f-8c8d-410da89646f9', firstName='First Name', lastName='Last Name}
Now fetch the user details with ID
User :User{id='0701f22b-10b0-4d6f-8c8d-410da89646f9', firstName='First Name', lastName='Last Name}
Now update the user details
User After Updation:User{id='0701f22b-10b0-4d6f-8c8d-410da89646f9', firstName='Bala', lastName='Samy}
Now delete the user details
User After Deletion:null


Testing HK2 injection
Fetching the various DAO implementation
UserDao userDao = serviceLocator.getService(UserDao.class, "empGuavaCacheDao")
userDao instanceof UserGuavaCacheImpl - > Its an instance of UserGuavaCacheImpl 
userDao = serviceLocator.getService(UserDao.class, "empLocalCacheDao")
userDao instanceof UserLocalCacheDaoImpl - > Its an instance of UserLocalCacheDaoImpl 


 

Refer the code @hk2-java-custombinder

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s