How to use HK2 injection in a Standalone Java Application

In this post, we are going to see how we can use the HK2 injection framework in a standalone Java application.

We need to include the below hk2 dependencies in our pom file. Here is the pom file.


 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <name>Hk2 Java standlaone application</name>
    <version>1.0.0</version>
    <artifactId>hk2-java-sample</artifactId>
    <groupId>com</groupId>
    <properties>
        <commons-lang3-v>3.6</commons-lang3-v>
        <maven-compiler-plugin-v>3.7.0</maven-compiler-plugin-v>
        <hk2-v>2.5.0-b36</hk2-v>
        <junit-v>4.12</junit-v>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons-lang3-v}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit-v}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.hk2</groupId>
            <artifactId>hk2</artifactId>
            <version>${hk2-v}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.hk2</groupId>
            <artifactId>hk2-junitrunner</artifactId>
            <version>${hk2-v}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-compiler-plugin-v}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.glassfish.hk2</groupId>
                <artifactId>hk2-inhabitant-generator</artifactId>
                <version>${hk2-v}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate-inhabitants</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Consider that, we have a standalone application which will be used for adding, deleting, updating the employee details and the back end is a HashMap.

We have two interfaces(EmployeeService and EmployeeDao) and its implemetation classes(EmployeeServiceImpl and EmployeeDaoImpl) in this application.

To make use of HK2 injection, All our interfaces should be annotated with @Contract and all the implementation classes should be annotated with @Service.

Refer the below code to know how to do that.


package com.service;

import com.model.Employee;
import org.jvnet.hk2.annotations.Contract;

@Contract
public interface EmployeeService {
    public Employee fetch(String id);
    public Employee add(Employee employee);
    public void delete(String id);
    public Employee update(Employee employee);
}



package com.service.impl;

import com.dao.EmployeeDao;
import com.model.Employee;
import com.service.EmployeeService;
import org.jvnet.hk2.annotations.Service;

import javax.inject.Inject;
import java.util.UUID;

@Service
public class EmployeeServiceImpl implements EmployeeService {

    private EmployeeDao employeeDao;

    @Inject
    public EmployeeServiceImpl(EmployeeDao employeeDao){
        this.employeeDao = employeeDao;
    }

    @Override
    public Employee fetch(String id) {
        return employeeDao.fetch(id);
    }

    @Override
    public Employee add(Employee employee) {
        employee.setId(UUID.randomUUID().toString());
        return employeeDao.add(employee);

    }

    @Override
    public void delete(String id) {
        employeeDao.delete(id);
    }

    @Override
    public Employee update(Employee employee) {
        return employeeDao.update(employee);
    }
}



package com.dao;

import com.model.Employee;
import org.jvnet.hk2.annotations.Contract;

@Contract
public interface EmployeeDao {

    public Employee fetch(String id);
    public Employee add(Employee employee);
    public void delete(String id);
    public Employee update(Employee employee);
}


package com.dao.impl;

import com.dao.EmployeeDao;
import com.model.Employee;
import org.jvnet.hk2.annotations.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class EmployeeDaoImpl implements EmployeeDao {

    private static Map empLocalCache = new HashMap();

    public Employee fetch(String id) {
        return empLocalCache.get(id);
    }

    public Employee add(Employee employee) {
        empLocalCache.put(employee.getId(), employee);
        return empLocalCache.get(employee.getId());
    }

    public void delete(String id) {
        empLocalCache.remove(id);
    }

    public Employee update(Employee employee) {
        empLocalCache.put(employee.getId(), employee);
        return empLocalCache.get(employee.getId());
    }
}


Below is my main class which will use the Employee service class to perform add, update and delete operations with Employee Object.


package com;

import com.model.Employee;
import com.service.EmployeeService;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.utilities.ServiceLocatorUtilities;

public class Application {

    public static void main(String[] args) {

        ServiceLocator serviceLocator = ServiceLocatorUtilities.createAndPopulateServiceLocator();
        EmployeeService employeeService = serviceLocator.getService(EmployeeService.class);
        Employee employee = new Employee();
        employee.setFirstName("First Name");
        employee.setLastName("Last Name");

        System.out.println("Add employee details");
        Employee employeeAddResponse = employeeService.add(employee);
        System.out.println("The employee details after it has been added Employee: "+employeeAddResponse);

        System.out.println("Now fetch the employee details with ID");
        Employee employeeFetchResponse = employeeService.fetch(employee.getId());
        System.out.println("Employee :"+employeeFetchResponse);

        System.out.println("Now update the employee details");
        employee.setFirstName("Bala");
        employee.setLastName("Samy");
        Employee employeeUpdateResponse = employeeService.update(employee);
        System.out.println("Employee After Updation:"+employeeUpdateResponse);

        System.out.println("Now delete the employee details");
        employeeService.delete(employee.getId());
        System.out.println("Employee After Deletion:"+ employeeService.fetch(employee.getId()));

    }
}


To initialize all the HK2 dependencies, we have to call the ServiceLocatorUtilities.createAndPopulateServiceLocator() which will perform the initialization and return the ServiceLocator object.

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

EmployeeService employeeService = serviceLocator.getService(EmployeeService.class);

Before executing this, we need to do an important step which is to create the hk2 default file under our target/classes/META-INF folder. The hk2-inhabitant-generator plugin will help us to generate that file. Hence we need to include this plugin in our file. So we have to do maven install/package before we start executing our junit test cases.

The sample default file content will be like this,

#
# Generated on Thu Nov 09 17:04:57 EST 2017 by hk2-inhabitant-generator
#

[com.dao.impl.EmployeeDaoImpl]S
contract={com.dao.EmployeeDao}

[com.service.impl.EmployeeServiceImpl]S
contract={com.service.EmployeeService}

The output of my program is given below,



Add employee details
The employee details after it has been added Employee: Employee{id='f25b119a-820e-4162-af99-5c3580fe06f1', firstName='First Name', lastName='Last Name}
Now fetch the employee details with ID
Employee :Employee{id='f25b119a-820e-4162-af99-5c3580fe06f1', firstName='First Name', lastName='Last Name}
Now update the employee details
Employee After Updation:Employee{id='f25b119a-820e-4162-af99-5c3580fe06f1', firstName='Bala', lastName='Samy}
Now delete the employee details
Employee After Deletion:null


 

Refer the code @hk2-java-sample

 

 

Advertisements