Tutorial

Google Guice Dependency Injection Example Tutorial

Published on August 3, 2022
author

Pankaj

Google Guice Dependency Injection Example Tutorial

Google Guice is the framework to automate the dependency injection in applications. If you have come across directly here, I would recommend you to check out Dependency Injection Example where we learned the problems with traditional approach of Object creation and implementation benefits of dependency injection. In last tutorial, we learned how can we implement dependency injection in applications manually. But when number of classes grow in an application, it’s better to look for some framework to automate this task. Google Guice is one of the leading frameworks whose main work is to provide automatic implementation of dependency injection. We will work on the same example from last post and learn how can we use Google Guice to automate the implementation process for dependency injection. Google Guice dependencies are available on maven central, so for maven projects you can add below dependency for it.

<dependency>
	<groupId>com.google.inject</groupId>
	<artifactId>guice</artifactId>
	<version>3.0</version>
</dependency>

If you have a simple java application, then you can download the jar file from Google Guice Home Page on Google Code. Note that in this case you will also need to have it’s transitive dependencies in the classpath or else you will get runtime exception. For my example, I have a maven project whose project structure looks like below image. Google Guice, Guice, Google Guice Example, Google Guice Tutorial, Guide dependency injection Let’s see each of the components one by one.

Service Classes

package com.journaldev.di.services;

public interface MessageService {

	boolean sendMessage(String msg, String receipient);
}

MessageService interface provides the base contract for the services.

package com.journaldev.di.services;

import javax.inject.Singleton;

//import com.google.inject.Singleton;

@Singleton
public class EmailService implements MessageService {

	public boolean sendMessage(String msg, String receipient) {
		//some fancy code to send email
		System.out.println("Email Message sent to "+receipient+" with message="+msg);
		return true;
	}

}

EmailService is one of the implementation of MessageService. Notice that class is annotated with @Singleton annotation. Since service objects will be created through injector classes, this annotation is provided to let them know that the service classes should be singleton objects. Google Guice 3.0 added the support for JSR-330 and we can use annotations from com.google.inject or javax.inject package. Let’s say we have another service implementation to send facebook messages.

package com.journaldev.di.services;

import javax.inject.Singleton;

//import com.google.inject.Singleton;

@Singleton
public class FacebookService implements MessageService {

	public boolean sendMessage(String msg, String receipient) {
		//some complex code to send Facebook message
		System.out.println("Message sent to Facebook user "+receipient+" with message="+msg);
		return true;
	}

}

Consumer Class

Since we are implementing dependency injection in our application, we won’t initialize the service class in application. Google Guice support both setter-based and constructor-based dependency injection. Our application class that consumes the service looks like below.

package com.journaldev.di.consumer;

import javax.inject.Inject;

//import com.google.inject.Inject;
import com.journaldev.di.services.MessageService;

public class MyApplication {

	private MessageService service;
	
//	constructor based injector
//	@Inject
//	public MyApplication(MessageService svc){
//		this.service=svc;
//	}
	
	//setter method injector
	@Inject
	public void setService(MessageService svc){
		this.service=svc;
	}
	
	public boolean sendMessage(String msg, String rec){
		//some business logic here
		return service.sendMessage(msg, rec);
	}
}

Notice that I have commented the code for constructor based injection, this comes handy when your application provides some other features too that doesn’t need service class object. Also notice the @Injector annotation, this will be used by Google Guice to inject the service implementation class. If you are not familiar with annotations, check out java annotations tutorial.

Binding Service implementation

Obviously google guice will not know which service to use, we have to configure it by extending AbstractModule abstract class and provide implementation for configure() method.

package com.journaldev.di.injector;

import com.google.inject.AbstractModule;
import com.journaldev.di.services.EmailService;
import com.journaldev.di.services.FacebookService;
import com.journaldev.di.services.MessageService;

public class AppInjector extends AbstractModule {

	@Override
	protected void configure() {
		//bind the service to implementation class
		//bind(MessageService.class).to(EmailService.class);
		
		//bind MessageService to Facebook Message implementation
		bind(MessageService.class).to(FacebookService.class);
		
	}

}

As you can see that we can bind any of the implementation to service class. For example, if we want to change to EmailService we would just need to change the bindings.

Client Application

Our setup is ready, let’s see how to use it with a simple java class.

package com.journaldev.di.test;

import com.google.inject.Guice;
import com.google.inject.Injector;

import com.journaldev.di.consumer.MyApplication;
import com.journaldev.di.injector.AppInjector;

public class ClientApplication {

	public static void main(String[] args) {
		Injector injector = Guice.createInjector(new AppInjector());		
		
		MyApplication app = injector.getInstance(MyApplication.class);
		
		app.sendMessage("Hi Pankaj", "pankaj@abc.com");
	}

}

The implementation is very easy to understand. We need to create Injector object using Guice class createInjector() method where we pass our injector class implementation object. Then we use injector to initialize our consumer class. If we run above class, it will produce following output.

Message sent to Facebook user pankaj@abc.com with message=Hi Pankaj

If we change the bindings to EmailService in AppInjector class then it will produce following output.

Email Message sent to pankaj@abc.com with message=Hi Pankaj

JUnit Test Cases

Since we want to test MyApplication class, we are not required to create actual service implementation. We can have a simple Mock service implementation class like below.

package com.journaldev.di.services;

public class MockMessageService implements MessageService{

	public boolean sendMessage(String msg, String receipient) {
		return true;
	}

}

My JUnit 4 test class looks like below.

package com.journaldev.di.test;


import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.journaldev.di.consumer.MyApplication;
import com.journaldev.di.services.MessageService;
import com.journaldev.di.services.MockMessageService;

public class MyApplicationTest {

	private Injector injector;
	
	@Before
	public void setUp() throws Exception {
		injector = Guice.createInjector(new AbstractModule() {
			
			@Override
			protected void configure() {
				bind(MessageService.class).to(MockMessageService.class);
			}
		});
	}

	@After
	public void tearDown() throws Exception {
		injector = null;
	}

	@Test
	public void test() {
		MyApplication appTest = injector.getInstance(MyApplication.class);
		Assert.assertEquals(true, appTest.sendMessage("Hi Pankaj", "pankaj@abc.com"));;
	}

}

Notice that I am binding MockMessageService class to MessageService by having an anonymous class implementation of AbstractModule. This is done in setUp() method that runs before the test methods.

Download Google Guice Project

That’s all for Google Guice Example Tutorial. Use of Google Guice for implementing dependency injection in application is very easy and it does it beautifully. It’s used in Google APIs so we can assume that it’s highly tested and reliable code. Download the project from above and play around with it to learn more.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Pankaj

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
February 27, 2021

awesome blog post… very helpful.

- RahulG

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    October 20, 2017

    Thanks, nice post

    - Binh Thanh Nguyen

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      April 17, 2017

      Very helpful.

      - Srini

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        April 10, 2017

        Hi pankaj, I imported the project in Intellij. Could you please tell me how to create a maven build conf. for that ?

        - Mayank Verma

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          March 19, 2017

          Thank you ! Guice for human arrived ! I used it for other projects but this time I found a really good introduction to understand the bases.

          - sbeex

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            August 16, 2016

            My Main java class: =================== package com.sample.test; import com.google.inject.Guice; import com.google.inject.Injector; public class mymain { public static void main(String[] args) { // TODO Auto-generated method stub Injector injector = Guice.createInjector(new AppInjectory()); ApplicationExample obj = injector.getInstance(ApplicationExample.class); obj.sendMessage(); } } My interface ============= package com.sample.test; public interface MessageService { boolean sendMessage(String msg, String receipient); } My config file ================== package com.sample.test; import com.google.inject.AbstractModule; public class AppInjectory extends AbstractModule { @Override protected void configure() { //bind the service to implementation class //bind(MessageService.class).to(EmailService.class); //bind MessageService to Facebook Message implementation bind(MessageService.class).to(EmailService.class); } } My appication file =================== package com.sample.test; import javax.inject.Inject; public class ApplicationExample { private MessageService service; @Inject public void setService(MessageService svc){ this.service=svc; } public void sendMessage() { System.out.println(“I am here”); service.sendMessage(“welcome”, “java”); } } My service class ===================== package com.sample.test; //import com.google.inject.Singleton; import javax.inject.Singleton; @Singleton public class EmailService implements MessageService { public boolean sendMessage(String msg, String receipient) { //some fancy code to send email System.out.println(“Email Message sent to “+receipient+” with message=”+msg); return true; } } Here I am getting NUll pointer exception .What wrong I did here.?please help to fix this issue. ERROR: Exception in thread “main” I am here java.lang.NullPointerException at com.sample.test.ApplicationExample.sendMessage(ApplicationExample.java:16) at com.sample.test.mymain.main(mymain.java:13)

            - lawri

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              May 26, 2016

              Thank you Pankaj, This is my third tutorial of yours that I have gone through and I think they are very well written.

              - David Adkins

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                April 7, 2016

                Your “Shares” dialog is obscuring the text of this article

                - Chris Beach

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  March 22, 2016

                  You can use assertTrue(…) instead of assertEquals(true, …)in your test. Looks better :)

                  - Rafal

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    March 15, 2016

                    property-based injection seams to work as well: public class RestResource { @Inject private IemandsService service; works like a charm

                    - Mark Muizer

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Become a contributor for community

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      DigitalOcean Documentation

                      Full documentation for every DigitalOcean product.

                      Resources for startups and SMBs

                      The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                      Get our newsletter

                      Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                      New accounts only. By submitting your email you agree to our Privacy Policy

                      The developer cloud

                      Scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Get started for free

                      Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                      *This promotional offer applies to new accounts only.