Set up Dependency Injection using Google Guice API with Example - Java @ Desk

Friday, December 12, 2014

Set up Dependency Injection using Google Guice API with Example

Set up Dependency Injection using Google Guice API with Example

In this post we will see how to set up Google Guice for to enable Dependency Injection in project. Google Guice is an Agile Lightweight framework for Dependency Injection in Java Using Annotation. Guice works on interface implementation, i.e. it allows binding of the Interface to the implementation.

Guice promote to "Programming to Interface and not for implementation" i.e. we Create the Interface and Implementation and its Responsibility of Guice Framework to create objects and resolve dependency at the run time. Guice helps to keep code clean, Meaningful, easy to test and maintainable.

Using the below Example I will be explaining how to setup Google Guice to enable the Dependency Injection. In the below example we will try to Inject Client in MainApplication and then Inject Service into the Client.

You can download the required Goole Gruice API from Google-Guice-3.0.zip. You need to extract .zip file and add all .jar files in the build path / .classpath of the project.

Let’s see the component one by one.




1. Configure Module to Enable the Dependency Injection

Create SampleModule.java which extends AbstractModule. Abstract Module have configure () method which we need to override.
Inside the configure() method need to define the Binding between the Interface and Corresponding Implementation as shown in the below example.

public class SampleModule extends AbstractModule {

 // Bind interface with Implementation in Configure Method.  
 @Override
 protected void configure() {
 // Bind Clinet to RESTFul WebService
 //bind(Client.class).to(RESTClient.class);
  
 // Bind Client to JMS Service.
 bind(Client.class).to(JMSClient.class);
  
 bind(JMSService.class).to(JMSServiceImpl.class);
 bind(RESTService.class).to(RESTServiceImpl.class);
 } 
}





2. Interfaces and Implementation

As shown in the above point we need to Create the Interface and Corresponding Implementation. For Example, JSMClient and RESTClient are the type of Client which can access the Service ( JMSService / RESTService).

Client.java

package com.code.java.desk.api; 
public interface Client {
 
 String accessService();
}

@Singleton
public class JMSClient implements Client {

 // Instance Variable Injection.
        @Inject
 private JMSService jmsService;
 
 // Constructor Based Injection
 @Inject
 public JMSClient(JMSService jmsService) {
  super();
  this.jmsService = jmsService;
 }

 // Setter Method Injection.
 @Inject
 public void setJMSService(JMSService service){
  this.jmsService = service;
 }

 @Override
 public String accessService() {
  System.out.println("Access Client....");
  jmsService.execute();
  System.out.println("Exit Client Code...");
 }

}


JMSClient.java is an Implementation of Interface Client.java.

In the Above Example you can see different types of Injection which Google Guice Supports -
i. Member Variable Injection – It’s responsibility of Guice to Inject the instance of member variable, as defined in configure() of SampleModule. Note - Can’t use Member variable inside the Constructor.
ii. Constructor Based Injection – Inject Member variable using the Constructor. Either the Class should have default constructor or need to apply @Inject Annotation on the Constructor.
iii. Setter Method based Injection – Need to apply @Inject Annotation on setter method, which Guice use to Inject the Variable.

Any or All of the above injection type can be used at a time.






3. Services and Implementation

Below defined as JMSService and JMSServiceImpl.

package com.code.java.desk.service;

public interface JMSService {

 void execute();
}

@Singleton
public class JMSServiceImpl implements JMSService{

 @Override
 public void execute() {
  System.out.println("Executing JMS Service");
 }
 
}


In the Above example we have used annotation @Singleton which denotes that only instance will be created for Above mentioned service by Guice Framework. It Implements Singleton Design Pattern using Guice.




4. MainApplication / User Interface

public class MainApplication {

 @Inject
 Client client;
 
 public String processRequest(){
  System.out.println("Inside the Main Application...");
  client.accessService();
  System.out.println("Exit Main Applicaion...");
 }
}


In the Main application, Guice Inject the instance of Client which has been bind in SampleModule using bind() and to().




5. Entry Point of Application

public class TestMainApplication {
 
 public static void main(String[] args) {
  
  Injector injector = Guice.createInjector(new SampleModule());
  MainApplication mainApp = injector.getInstance(MainApplication.class);
  mainApp.processRequest();
 }
}


In the Above mentioned way we can get the instance of Injector from the sameple Module.

We can get the Instance of any class defined in the project using the Injector with condition either have a Default Constructor or Parameterized constructor with @Inject annotation.




6. How to Write JUnit test cases for Google Guice

To Write the test case for functionalities using Guice, we need to Create the instance of Injector using the Module. We can Install the SampleModule which we had created. Need to Bind the necessary services, interface and implementation and install the existing module( If Necessary). Following is the example to show case –
public class MainApplicationTest {

    private Injector injector;
 @Before
 public void setUp() throws Exception {
          injector = Guice.createInjector(new AbstractModule() {
             
            @Override
            protected void configure() {
  install(new SampleModule());
                 bind(JMSService.class).to(JMSServiceImpl.class);
                 bind(Client.class).to(JMSClient.class);
            }
        });
    }
 
     @After
     public void destroy() throws Exception {
          injector = null;
    }
@Test
 public void testProcessRequest() {
  MainApplication mainApp = injector.getInstance(MainApplication.class);
  Assert.assertEquals("Executing JMS Service",mainApp.processRequest());
  }
}


Output -----------

Inside the Main Application...
Access Client....
Executing JMS Service

----------------------------------

User can run the Application either using test case MainApplicationTest.java or TestMainApplication.java.

This post is written by
Soumitra Pathak - Linkedin, Facebook
He is a freelance writer, loves to explore latest features in Java technology.








No comments:

Post a Comment