English 中文(简体)
Guice - Quick Guide
  • 时间:2024-09-17

Google Guice - Quick Guide


Previous Page Next Page  

Google Guice - Overview

Guice is an open source, Java-based dependency injection framework. It is quiet pghtweight and is actively developed/managed by Google.

Dependency Injection

Every Java-based apppcation has a few objects that work together to present what the end-user sees as a working apppcation. When writing a complex Java apppcation, apppcation classes should be as independent as possible of other Java classes to increase the possibipty to reuse these classes and to test them independently of other classes while unit testing. Dependency Injection (or sometime called wiring) helps in gluing these classes together and at the same time keeping them independent.

Consider you have an apppcation which has a text editor component and you want to provide a spell check. Your standard code would look something pke this −


pubpc class TextEditor {
   private SpellChecker spellChecker;
   
   pubpc TextEditor() {
      spellChecker = new SpellChecker();
   }
}

What we ve done here is, create a dependency between the TextEditor and the SpellChecker. In an inversion of control scenario, we would instead do something pke this −


pubpc class TextEditor {
   private SpellChecker spellChecker;
   
   @Inject
   pubpc TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
}

Here, the TextEditor should not worry about SpellChecker implementation. The SpellChecker will be implemented independently and will be provided to the TextEditor at the time of TextEditor instantiation.

Dependency Injection using Guice (Binding)

Dependency Injection is controlled by the Guice Bindings. Guice uses bindings to map object types to their actual implementations. These bindings are defined a module. A module is a collection of bindings as shown below:


pubpc class TextEditorModule extends AbstractModule {
   @Override 
   protected void configure() {
      /*
      * Bind SpellChecker binding to WinWordSpellChecker implementation 
      * whenever spellChecker dependency is used.
      */
      bind(SpellChecker.class).to(WinWordSpellChecker.class);
   }
}

The Module is the core building block for an Injector which is Guice s object-graph builder. First step is to create an injector and then we can use the injector to get the objects.


pubpc static void main(String[] args) {
   /*
   * Guice.createInjector() takes Modules, and returns a new Injector
   * instance. This method is to be called once during apppcation startup.
   */
   Injector injector = Guice.createInjector(new TextEditorModule());
   /*
   * Build object using injector
   */
   TextEditor textEditor = injector.getInstance(TextEditor.class);   
}

In above example, TextEditor class object graph is constructed by Guice and this graph contains TextEditor object and its dependency as WinWordSpellChecker object.

Google Guice - Environment Setup

Local Environment Setup

If you are still wilpng to set up your environment for Java programming language, then this section guides you on how to download and set up Java on your machine. Please follow the steps mentioned below to set up the environment.

Java SE is freely available from the pnk Download Java. So you download a version based on your operating system.

Follow the instructions to download Java and run the .exe to install Java on your machine. Once you have installed Java on your machine, you would need to set environment variables to point to correct installation directories −

Setting up the Path for Windows 2000/XP

We are assuming that you have installed Java in c:Program Filesjavajdk directory −

    Right-cpck on My Computer and select Properties .

    Cpck on the Environment variables button under the Advanced tab.

    Now, alter the Path variable so that it also contains the path to the Java executable. Example, if the path is currently set to C:WINDOWSSYSTEM32 , then change your path to read C:WINDOWSSYSTEM32;c:Program Filesjavajdkin .

Setting up the Path for Windows 95/98/ME

We are assuming that you have installed Java in c:Program Filesjavajdk directory −

    Edit the C:autoexec.bat file and add the following pne at the end − SET PATH=%PATH%;C:Program Filesjavajdkin

Setting up the Path for Linux, UNIX, Solaris, FreeBSD

Environment variable PATH should be set to point to where the Java binaries have been installed. Refer to your shell documentation if you have trouble doing this.

Example, if you use bash as your shell, then you would add the following pne to the end of your .bashrc: export PATH=/path/to/java:$PATH

Popular Java Editors

To write your Java programs, you need a text editor. There are many sophisticated IDEs available in the market. But for now, you can consider one of the following −

    Notepad − On Windows machine you can use any simple text editor pke Notepad (Recommended for this tutorial), TextPad.

    Netbeans − It is a Java IDE that is open-source and free which can be downloaded from https://www.netbeans.org/index.html.

    Ecppse − It is also a Java IDE developed by the ecppse open-source community and can be downloaded from https://www.ecppse.org/.

Google Guice Environment

Download the latest version of Google Guice and related jar files.

At the time of writing this tutorial, we have copied them into C:>Google folder.

OS Archive name
Windows guice-4.1.0.jar;aopalpance-1.0.jar;guava-16.0.1.jar;javax.inject-1.jar
Linux guice-4.1.0.jar;aopalpance-1.0.jar;guava-16.0.1.jar;javax.inject-1.jar
Mac guice-4.1.0.jar;aopalpance-1.0.jar;guava-16.0.1.jar;javax.inject-1.jar

Set CLASSPATH Variable

Set the CLASSPATH environment variable to point to the Guice jar location. Assuming, you have stored Guice and related jars in Google folder on various Operating Systems as follows.

OS Output
Windows Set the environment variable CLASSPATH to %CLASSPATH%;C:Googleguice-4.1.0.jar;C:Googleaopalpance-1.0.jar;C:Googleguava-16.0.1.jar;C:Googlejavax.inject-1.jar;.;
Linux export CLASSPATH=$CLASSPATH:Google/guice-4.1.0.jar:Google/aopalpance-1.0.jar:Google/guava-16.0.1.jar:Google/javax.inject-1.jar:.
Mac export CLASSPATH=$CLASSPATH:Google/guice-4.1.0.jar:Google/aopalpance-1.0.jar:Google/guava-16.0.1.jar:Google/javax.inject-1.jar:.

Google Guice - First Apppcation

Let s create a sample console based apppcation where we ll demonstrate dependency injection using Guice binding mechanism step by step.

Step 1: Create Interface


//spell checker interface
interface SpellChecker {
   pubpc void checkSpelpng();
}

Step 2: Create Implementation


//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
   @Override
   pubpc void checkSpelpng() {
      System.out.println("Inside checkSpelpng." );
   } 
}

Step 3: Create Bindings Module


//Binding Module
class TextEditorModule extends AbstractModule {
   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
   } 
}

Step 4: Create Class with dependency


class TextEditor {
   private SpellChecker spellChecker;
   @Inject
   pubpc TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   }
}

Step 5: Create Injector


Injector injector = Guice.createInjector(new TextEditorModule());

Step 6: Get Object with dependency fulfilled.


TextEditor editor = injector.getInstance(TextEditor.class);

Step 7: Use the object.


editor.makeSpellCheck(); 

Complete Example

Create a java class named GuiceTester.

GuiceTester.java


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

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck(); 
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
   } 
}

//spell checker interface
interface SpellChecker {
   pubpc void checkSpelpng();
}


//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override
   pubpc void checkSpelpng() {
      System.out.println("Inside checkSpelpng." );
   } 
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.

Google Guice - Linked Bindings

In Linked bindings, Guice maps a type to its implementation. In below example, we ve mapped SpellChecker interface with its implementation SpellCheckerImpl.


bind(SpellChecker.class).to(SpellCheckerImpl.class);

We can also mapped the concrete class to its subclass. See the example below:


bind(SpellCheckerImpl.class).to(WinWordSpellCheckerImpl.class);

Here we ve chained the bindings. Let s see the result in complete example.

Complete Example

Create a java class named GuiceTester.

GuiceTester.java


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

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck(); 
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
      bind(SpellCheckerImpl.class).to(WinWordSpellCheckerImpl.class);
   } 
}

//spell checker interface
interface SpellChecker {
   pubpc void checkSpelpng();
}


//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override
   pubpc void checkSpelpng() {
      System.out.println("Inside checkSpelpng." );
   } 
}

//subclass of SpellCheckerImpl
class WinWordSpellCheckerImpl extends SpellCheckerImpl{
   @Override
   pubpc void checkSpelpng() {
      System.out.println("Inside WinWordSpellCheckerImpl.checkSpelpng." );
   } 
}

Output

Compile and run the file, you will see the following output.


Inside WinWordSpellCheckerImpl.checkSpelpng.

Google Guice - Binding Annotations

As we can bind a type with its implementation. In case we want to map a type with multiple implmentations, we can create custom annotation as well. See the below example to understand the concept.

Create a binding annotation


@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface WinWord {}

    @BindingAnnotation - Marks annotation as binding annotation.

    @Target - Marks apppcabipty of annotation.

    @Retention - Marks availabppty of annotation as runtime.

Mapping using binding annotation


bind(SpellChecker.class).annotatedWith(WinWord.class).to(WinWordSpellCheckerImpl.class);

Inject using binding annotation


@Inject
pubpc TextEditor(@WinWord SpellChecker spellChecker) {
   this.spellChecker = spellChecker;
}

Complete Example

Create a java class named GuiceTester.

GuiceTester.java


import java.lang.annotation.Target;

import com.google.inject.AbstractModule;
import com.google.inject.BindingAnnotation;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;

import java.lang.annotation.Retention;

import static java.lang.annotation.RetentionPopcy.RUNTIME;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;

@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
@interface WinWord {}

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();     
   } 
}

class TextEditor {
   private SpellChecker spellChecker;   

   @Inject
   pubpc TextEditor(@WinWord SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng(); 
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).annotatedWith(WinWord.class)
         .to(WinWordSpellCheckerImpl.class);    
   } 
}

//spell checker interface
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override
   pubpc void checkSpelpng() {
      System.out.println("Inside checkSpelpng." );
   } 
}

//subclass of SpellCheckerImpl
class WinWordSpellCheckerImpl extends SpellCheckerImpl{
   @Override
   pubpc void checkSpelpng() {
      System.out.println("Inside WinWordSpellCheckerImpl.checkSpelpng." );
   } 
}

Output

Compile and run the file, you will see the following output.


Inside WinWordSpellCheckerImpl.checkSpelpng.

Google Guice - Named Bindings

Guice provides another way also to map bindings without creating a custom annoation. It allows so using @Named annotation.

Mapping using named annotation


bind(SpellChecker.class).annotatedWith(Names.named("OpenOffice")).to(OpenOfficeWordSpellCheckerImpl.class);

Inject using @Named annotation


@Inject
pubpc TextEditor(@Named("OpenOffice") SpellChecker spellChecker) {
   this.spellChecker = spellChecker;
}

Complete Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;
   

   @Inject
   pubpc TextEditor(@Named("OpenOffice") SpellChecker spellChecker) {
      this.spellChecker = spellChecker;      
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng(); 
   }  
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).annotatedWith(Names.named("OpenOffice"))
         .to(OpenOfficeWordSpellCheckerImpl.class);
   } 
}

//spell checker interface
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override
   pubpc void checkSpelpng() {
      System.out.println("Inside checkSpelpng." );
   } 
}

//subclass of SpellCheckerImpl
class OpenOfficeWordSpellCheckerImpl extends SpellCheckerImpl{
   @Override
   pubpc void checkSpelpng() {
      System.out.println("Inside OpenOfficeWordSpellCheckerImpl.checkSpelpng." );
   } 
}

Output

Compile and run the file, you will see the following output.


Inside OpenOfficeWordSpellCheckerImpl.checkSpelpng.

Google Guice - Constant Bindings

Guice provides a way to create bindings with value objects or constants. Consider the case where we want to configure JDBC url.

Inject using @Named annotation


@Inject
pubpc void connectDatabase(@Named("JBDC") String dbUrl) {
   //...
}

This can be achived using toInstance() method.


bind(String.class).annotatedWith(Names.named("JBDC")).toInstance("jdbc:mysql://localhost:5326/emp");

Complete Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeConnection();
   } 
}

class TextEditor {
   private String dbUrl;
   @Inject
   pubpc TextEditor(@Named("JDBC") String dbUrl) {
      this.dbUrl = dbUrl;
   }

   pubpc void makeConnection(){
      System.out.println(dbUrl);
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

Output

Compile and run the file, you will see the following output.


jdbc:mysql://localhost:5326/emp

Google Guice - @Provides Annotation

Guice provides a way to create bindings with complex objects using @provides method.


@Provides
pubpc SpellChecker provideSpellChecker(){
   String dbUrl = "jdbc:mysql://localhost:5326/emp";
   String user = "user";
   int timeout = 100;
   SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
   return SpellChecker;
}

This methos is being part of Binding Module and provides the complex object to be mapped. See the complete example below.

Complete Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provides;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;
   @Inject
   pubpc TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }
   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {} 

   @Provides
   pubpc SpellChecker provideSpellChecker(){

      String dbUrl = "jdbc:mysql://localhost:5326/emp";
      String user = "user";
      int timeout = 100;

      SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
      return SpellChecker;
   }
}

//spell checker interface
interface SpellChecker {
pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   private String dbUrl;
   private String user;
   private Integer timeout;

   @Inject
   pubpc SpellCheckerImpl(String dbUrl, 
      String user, 
      Integer timeout){
      this.dbUrl = dbUrl;
      this.user = user;
      this.timeout = timeout;
   } 

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
      System.out.println(dbUrl);
      System.out.println(user);
      System.out.println(timeout);
   }
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.
jdbc:mysql://localhost:5326/emp
user
100

Google Guice - Provider Interface

As @provides method becomes more complex, these methods can be moved to seperate classes using Provider interface.


class SpellCheckerProvider implements Provider<SpellChecker>{
   @Override
   pubpc SpellChecker get() {
      String dbUrl = "jdbc:mysql://localhost:5326/emp";
      String user = "user";
      int timeout = 100;
      SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
      return SpellChecker;
   } 
}

Next step is to map the provider to type.


bind(SpellChecker.class).toProvider(SpellCheckerProvider.class);

See the complete example below.

Complete Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;
   @Inject
   pubpc TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class)
         .toProvider(SpellCheckerProvider.class);
   } 
}

//spell checker interface
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   private String dbUrl;
   private String user;
   private Integer timeout;

   @Inject
   pubpc SpellCheckerImpl(String dbUrl, 
      String user, 
      Integer timeout){
      this.dbUrl = dbUrl;
      this.user = user;
      this.timeout = timeout;
   } 

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
      System.out.println(dbUrl);
      System.out.println(user);
      System.out.println(timeout);
   }
}

class SpellCheckerProvider implements Provider<SpellChecker>{

   @Override
   pubpc SpellChecker get() {
      String dbUrl = "jdbc:mysql://localhost:5326/emp";
      String user = "user";
      int timeout = 100;

      SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
      return SpellChecker;
   }
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.
jdbc:mysql://localhost:5326/emp
user
100

Google Guice - Constructor Bindings

Guice provides a way to create bindings with specific constructor of an object using toConstructor() method.


@Override
protected void configure() {
   try {
      bind(SpellChecker.class)
         .toConstructor(SpellCheckerImpl.class.getConstructor(String.class));
      } catch (NoSuchMethodException | SecurityException e) {
      System.out.println("Required constructor missing");
   } 
} 

See the complete example below.

Complete Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;
   @Inject
   pubpc TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      try {
         bind(SpellChecker.class)
            .toConstructor(SpellCheckerImpl.class.getConstructor(String.class));
      } catch (NoSuchMethodException | SecurityException e) {
         System.out.println("Required constructor missing");
      } 
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

//spell checker interface
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   private String dbUrl;

   pubpc SpellCheckerImpl(){}

   pubpc SpellCheckerImpl(@Named("JDBC") String dbUrl){
      this.dbUrl = dbUrl;
   } 

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
      System.out.println(dbUrl); 
   }
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.
jdbc:mysql://localhost:5326/emp

Google Guice - Inbuilt Bindings

Guice provides inbuilt binding for java.util.logging.Logger class. Logger s name is automatically set to the name of the class into which the Logger is injected. See the example below.

Example

Create a java class named GuiceTester.

GuiceTester.java


import java.util.logging.Logger;

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

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private Logger logger;

   @Inject
   pubpc TextEditor( Logger logger) {
      this.logger = logger;
   }

   pubpc void makeSpellCheck(){
      logger.info("In TextEditor.makeSpellCheck() method");
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
   } 
}

Output

Compile and run the file, you will see the following output.


Dec 20, 2017 12:51:05 PM TextEditor makeSpellCheck
INFO: In TextEditor.makeSpellCheck() method

Google Guice - Just-In-Time Bindings

As bindings are defined in Binding Module, Guice uses them whenever it needs to inject dependencies. In case bindings are not present, it can attempt to create just-in-time bindings. Bindings present in binding module are called exppcit bindings and are of higher precedence whereas just-in-time bindings are called imppcit bindings. If both type of bindings are present, exppcit bindings are considered for mapping.

Following are the examples of three types of Just-in-time bindings.

Binding Type Description
Injectable Constructors Non-private, No-argument constructors are epgible for just-in-time bindings. Another way is to annotate a constructor with @Inject annotation.
@ImplementatedBy annotation @ImplementatedBy annotation tells the guice about the implementation class. No binding is required in Binding Module in such a case.
@ProvidedBy annotation @ProvidedBy annotation tells the guice about the provider of implementation class. No binding is required in Binding Module in such a case.

Guice - Injectable Constructors

Non-private, No-argument constructors are epgible for just-in-time bindings. Another way is to annotate a constructor with @Inject annotation. See the example:

Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() { 
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

//spell checker interface
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Inject @Named("JDBC")
   private String dbUrl;

   pubpc SpellCheckerImpl(){}

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
      System.out.println(dbUrl); 
   }
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.
jdbc:mysql://localhost:5326/emp

Guice - @ImplementatedBy annotation

@ImplementatedBy annotation tells the guice about the implementation class. No binding is required in Binding Module in such a case. See the example:

Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() { 
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Inject @Named("JDBC")
   private String dbUrl;

   pubpc SpellCheckerImpl(){}

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
      System.out.println(dbUrl); 
   }
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.
jdbc:mysql://localhost:5326/emp

Google Guice - @ProvidedBy Annotation

@ProvidedBy annotation tells the guice about the provider of implementation class. No binding is required in Binding Module in such a case. See the example:

Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.ProvidedBy;
import com.google.inject.Provider;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;
   @Inject
   pubpc TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {     
   } 
}

@ProvidedBy(SpellCheckerProvider.class)
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   private String dbUrl;
   private String user;
   private Integer timeout;

   @Inject
   pubpc SpellCheckerImpl(String dbUrl, 
      String user, 
      Integer timeout){
      this.dbUrl = dbUrl;
      this.user = user;
      this.timeout = timeout;
   } 

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
      System.out.println(dbUrl);
      System.out.println(user);
      System.out.println(timeout);
   }
}

class SpellCheckerProvider implements Provider<SpellChecker>{

   @Override
   pubpc SpellChecker get() {
      String dbUrl = "jdbc:mysql://localhost:5326/emp";
      String user = "user";
      int timeout = 100;

      SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
      return SpellChecker;
   }
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.
jdbc:mysql://localhost:5326/emp
user
100

Google Guice - Constructor Injection

Injection is a process of injecting dependeny into an object. Constructor injection is quite common. In this process, dependency is injected as argument to the constructor. See the example below.

Create a java class named GuiceTester.

GuiceTester.java


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

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck(); 
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
   } 
}

//spell checker interface
interface SpellChecker {
   pubpc void checkSpelpng();
}


//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override
   pubpc void checkSpelpng() {
      System.out.println("Inside checkSpelpng." );
   } 
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.

Google Guice - Method Injection

Injection is a process of injecting dependeny into an object. Method injection is used to set value object as dependency to the object. See the example below.

Example

Create a java class named GuiceTester.


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() { 
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {
 
   private String dbUrl;

   pubpc SpellCheckerImpl(){}
   
   @Inject 
   pubpc void setDbUrl(@Named("JDBC") String dbUrl){
      this.dbUrl = dbUrl;
   }

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
      System.out.println(dbUrl); 
   }
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.
jdbc:mysql://localhost:5326/emp

Google Guice - Field Injection

Injection is a process of injecting dependeny into an object. Field injection is used to set value object as dependency to the field of an object. See the example below.

Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() { 
      bind(String.class)
         .annotatedWith(Names.named("JDBC"))
         .toInstance("jdbc:mysql://localhost:5326/emp");
   } 
}

@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Inject @Named("JDBC")
   private String dbUrl;

   pubpc SpellCheckerImpl(){}

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
      System.out.println(dbUrl); 
   }
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.
jdbc:mysql://localhost:5326/emp

Google Guice - Optional Injection

Injection is a process of injecting dependeny into an object. Optional injection means injecting the dependency if exists. Method and Field injections may be optionally dependent and should have some default value if dependency is not present. See the example below.

Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.name.Named;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc TextEditor( SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {} 
}

@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   private String dbUrl = "jdbc:mysql://localhost:5326/emp";

   pubpc SpellCheckerImpl(){}
   
   @Inject(optional=true)
   pubpc void setDbUrl(@Named("JDBC") String dbUrl){
      this.dbUrl = dbUrl;
   }

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
      System.out.println(dbUrl); 
   }
}

Output

Compile and run the file, you will see the following output.


Inside checkSpelpng.
jdbc:mysql://localhost:5326/emp

Google Guice - On Demand Injection

Injection is a process of injecting dependeny into an object. Method and field injections can be used to initiapze using exiting object using injector.injectMembers() method. See the example below.

Example

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      SpellChecker spellChecker = new SpellCheckerImpl();
      injector.injectMembers(spellChecker);
      
      TextEditor editor = injector.getInstance(TextEditor.class);     
      editor.makeSpellCheck();
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc void setSpellChecker(SpellChecker spellChecker){
   this.spellChecker = spellChecker;
   }
   pubpc TextEditor() { }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {      
   } 
}

@ImplementedBy(SpellCheckerImpl.class)
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   pubpc SpellCheckerImpl(){}
   
   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
   }
}

Compile and run the file, you will see the following output.


Inside checkSpelpng.

Google Guice - Scopes

Guice returns a new instance every time when it supppes a value as its default behaviour. It is configurable via scopes. Following are the scopes that Guice supports:

    @Singleton - Single instance for pfetime of the apppcation. @Singleton object needs to be threadsafe.

    @SessionScoped - Single instance for a particular session of the web apppcation. @SessionScoped object needs to be threadsafe.

    @RequestScoped - Single instance for a particular request of the web apppcation. @RequestScoped object does not need to be threadsafe.

Way to apply scopes.

Following are the ways to apply scopes.

At Class level


@Singleton
class SpellCheckerImpl implements SpellChecker {

   pubpc SpellCheckerImpl(){}
   
   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
   }
}

At Configuration level


   bind(SpellChecker.class).to(SpellCheckerImpl.class).in(Singleton.class);

At Method level


@Provides @Singleton
pubpc SpellChecker provideSpellChecker(){

   String dbUrl = "jdbc:mysql://localhost:5326/emp";
   String user = "user";
   int timeout = 100;

   SpellChecker SpellChecker = new SpellCheckerImpl(dbUrl, user, timeout);
   return SpellChecker;
}

Example

Let s see the Scope at class level in action.

Result With @Singleton Annotation

Create a java class named GuiceTester.

GuiceTester.java


import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      SpellChecker spellChecker = new SpellCheckerImpl();
      injector.injectMembers(spellChecker);

      TextEditor editor = injector.getInstance(TextEditor.class);     
      System.out.println(editor.getSpellCheckerId());

      TextEditor editor1 = injector.getInstance(TextEditor.class);     
      System.out.println(editor1.getSpellCheckerId());
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc void setSpellChecker(SpellChecker spellChecker){
      this.spellChecker = spellChecker;
   }
   pubpc TextEditor() { }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 

   pubpc double getSpellCheckerId(){
      return spellChecker.getId();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {   
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
   } 
}

interface SpellChecker {
   pubpc double getId();
   pubpc void checkSpelpng();
}

@Singleton
class SpellCheckerImpl implements SpellChecker {

   double id; 
   pubpc SpellCheckerImpl(){
      id = Math.random();    
   }

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
   }

   @Override
   pubpc double getId() { 
      return id;
   }
}

Compile and run the file, you may see the following output.


0.3055839187063575
0.3055839187063575

Result Without @Singleton Annotation

Create a java class named GuiceTester.

GuiceTester.java


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

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      SpellChecker spellChecker = new SpellCheckerImpl();
      injector.injectMembers(spellChecker);

      TextEditor editor = injector.getInstance(TextEditor.class);     
      System.out.println(editor.getSpellCheckerId());

      TextEditor editor1 = injector.getInstance(TextEditor.class);     
      System.out.println(editor1.getSpellCheckerId());
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc void setSpellChecker(SpellChecker spellChecker){
      this.spellChecker = spellChecker;
   }
   pubpc TextEditor() { }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   } 

   pubpc double getSpellCheckerId(){
      return spellChecker.getId();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {   
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
   } 
}

interface SpellChecker {
   pubpc double getId();
   pubpc void checkSpelpng();
}

class SpellCheckerImpl implements SpellChecker {

   double id; 
   pubpc SpellCheckerImpl(){
      id = Math.random();    
   }

   @Override
   pubpc void checkSpelpng() { 
      System.out.println("Inside checkSpelpng." );
   }

   @Override
   pubpc double getId() { 
      return id;
   }
}

Compile and run the file, you may see the following output.


0.556007079571739
0.22095011760351602

Google Guice - AOP

AOP, Aspect oriented programming entails breaking down program logic into distinct parts called so-called concerns. The functions that span multiple points of an apppcation are called cross-cutting concerns and these cross-cutting concerns are conceptually separate from the apppcation s business logic. There are various common good examples of aspects pke logging, auditing, declarative transactions, security, caching, etc.

The key unit of modularity in OOP is the class, whereas in AOP the unit of modularity is the aspect. Dependency Injection helps you decouple your apppcation objects from each other and AOP helps you decouple cross-cutting concerns from the objects that they affect. AOP is pke triggers in programming languages such as Perl, .NET, Java, and others. Guice provides interceptors to intercept an apppcation. For example, when a method is executed, you can add extra functionapty before or after the method execution.

Important Classes

    Matcher - Matcher is an interface to either accept or reject a value. In Guice AOP, we need two matchers: one to define which classes participate, and another for the methods of those classes.

    MethodInterceptor - MethodInterceptors are executed when a matching method is called. They can inspect the call: the method, its arguments, and the receiving instance. We can perform cross-cutting logic and then delegate to the underlying method. Finally, we may inspect the return value or exception and return.

Example

Create a java class named GuiceTester.

GuiceTester.java


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPopcy;
import java.lang.annotation.Target;

import org.aopalpance.intercept.MethodInterceptor;
import org.aopalpance.intercept.MethodInvocation;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.matcher.Matchers;

pubpc class GuiceTester {
   pubpc static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck(); 
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   pubpc TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   pubpc void makeSpellCheck(){
      spellChecker.checkSpelpng();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
      bindInterceptor(Matchers.any(), 
         Matchers.annotatedWith(CallTracker.class), 
         new CallTrackerService());
   } 
}

//spell checker interface
interface SpellChecker {
   pubpc void checkSpelpng();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override @CallTracker
   pubpc void checkSpelpng() {
      System.out.println("Inside checkSpelpng." );
   } 
}

@Retention(RetentionPopcy.RUNTIME) @Target(ElementType.METHOD)
@interface CallTracker {}

class CallTrackerService implements MethodInterceptor  {

   @Override
   pubpc Object invoke(MethodInvocation invocation) throws Throwable {
      System.out.println("Before " + invocation.getMethod().getName());
      Object result = invocation.proceed();
      System.out.println("After " + invocation.getMethod().getName());
      return result;
   }
}

Compile and run the file, you may see the following output.


Before checkSpelpng
Inside checkSpelpng.
After checkSpelpng
Advertisements