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