This tutorial focuses on constructor injection for Guice in detail. We will go through the detailed code and steps to explain.

Based on the environment


technology version
Java 1.8 +
Guice holdings

Initialize the project


  • Initialize the project
mvn archetype:generate -DgroupId=io.edurt.lc.guice -DartifactId=guice-binder-constructor - DarchetypeArtifactId = maven archetype - quickstart - Dversion = 1.0.0 - DinteractiveMode =false
Copy the code
  • Modify pom.xml to add Guice dependency

      
<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/xsd/maven-4.0.0.xsd">

    <parent>
        <artifactId>lc-guice</artifactId>
        <groupId>io.edurt.lc.guice</groupId>
        <version>1.0.0</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>guice-binder-constructor</artifactId>
    <name>Learning Center for Guice Binder(Constructor)</name>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>holdings</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>
Copy the code

Guice: Guice is the dependency that our core uses

Constructor injection


In Guice we can inject the entity information we need directly into any place we want by using the constructor, which is illustrated by an example.

  • insrc/main/javaCreating a Directoryio.edurt.lc.guice.GuiceConstructorServiceClass file, enter the following content in the file
package io.edurt.lc.guice;

import com.google.inject.ImplementedBy;

@ImplementedBy(GuiceConstructorServiceImpl.class)
public interface GuiceConstructorService
{
    void print(String source);
}
Copy the code
  • insrc/main/javaCreating a Directoryio.edurt.lc.guice.GuiceConstructorServiceImplClass file, enter the following content in the file
package io.edurt.lc.guice;

public class GuiceConstructorServiceImpl
        implements GuiceConstructorService
{
    @Override
    public void print(String source)
    {
        System.out.println(String.format("Hello Guice Binder For Constructor, %s", source)); }}Copy the code
  • The next insrc/test/javaThe directory to createio.edurt.lc.guice.TestGuiceConstructorTo test the service defined by the class file, add the following code
package io.edurt.lc.guice;

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

public class TestGuiceConstructor
{
    private GuiceConstructorService service;

    @Inject
    public TestGuiceConstructor(GuiceConstructorService service)
    {
        this.service = service;
    }

    public GuiceConstructorService getService(a)
    {
        return service;
    }

    public static void main(String[] args)
    {
        TestGuiceConstructor test = Guice.createInjector().getInstance(TestGuiceConstructor.class);
        test.getService().print("Test Case 1"); }}Copy the code

After running the unit test, the console prints the following:

Hello Guice Binder For Constructor, Test Case 1
Copy the code

This example is easy to understand. What it really means is that we Inject the GuiceConstructorService interface into the TestGuiceConstructor application via @Inject. Of course, we through @ ImplementedBy (GuiceConstructorServiceImpl. Class) to achieve the similar GuiceConstructorService service = new GuiceConstructorServiceImpl (), but each will generate a new instance, if you need a singleton pattern, requires a separate operation.

Note: In this application we did not associate the Module with Guice so that we could quickly test the application etc. We can’t inject through a non-Guice container, and here’s an example of an error: Static also can’t inject

package io.edurt.lc.guice;

import com.google.inject.Inject;

public class TestGuiceConstructorNo
{
    @Inject
    private GuiceConstructorService service;

    public GuiceConstructorService getService(a)
    {
        return service;
    }

    public static void main(String[] args)
    {
        TestGuiceConstructorNo test = new TestGuiceConstructorNo();
        test.getService().print("Test Case 1"); }}Copy the code

When we run the above code, we get the following error message

Exception in thread "main" java.lang.NullPointerException
	at io.edurt.lc.guice.TestGuiceConstructorNo.main(TestGuiceConstructorNo.java:18)
Copy the code

This means that instance injection cannot be done in a non-Guice container

Multiparameter injection


In the example above we only injected one parameter, so let’s try multi-parameter injection.

  • insrc/main/javaCreating a Directoryio.edurt.lc.guice.GuiceConstructorTwoServiceClass file, enter the following content in the file
package io.edurt.lc.guice;

import com.google.inject.ImplementedBy;

@ImplementedBy(GuiceConstructorTwoServiceImpl.class)
public interface GuiceConstructorTwoService
{
    void print(a);
}
Copy the code
  • insrc/main/javaCreating a Directoryio.edurt.lc.guice.GuiceConstructorTwoServiceImplClass file, enter the following content in the file
package io.edurt.lc.guice;

public class GuiceConstructorTwoServiceImpl
        implements GuiceConstructorTwoService
{
    @Override
    public void print(a)
    {
        System.out.println(String.format("Hello Guice Binder For Constructor Two")); }}Copy the code
  • The next insrc/test/javaThe directory to createio.edurt.lc.guice.TestGuiceConstructorMultipleTo test the service defined by the class file, add the following code
package io.edurt.lc.guice;

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

public class TestGuiceConstructorMultiple
{
    private GuiceConstructorService service;
    private GuiceConstructorTwoService twoService;

    public GuiceConstructorService getService(a)
    {
        return service;
    }

    public void setService(GuiceConstructorService service)
    {
        this.service = service;
    }

    public GuiceConstructorTwoService getTwoService(a)
    {
        return twoService;
    }

    public void setTwoService(GuiceConstructorTwoService twoService)
    {
        this.twoService = twoService;
    }

    @Inject
    public TestGuiceConstructorMultiple(GuiceConstructorService service, GuiceConstructorTwoService twoService)
    {
        this.service = service;
        this.twoService = twoService;
    }

    public static void main(String[] args)
    {
        TestGuiceConstructorMultiple multiple = Guice.createInjector().getInstance(TestGuiceConstructorMultiple.class);
        multiple.getService().print("One"); multiple.getTwoService().print(); }}Copy the code

After running the program, output the following results

Hello Guice Binder For Constructor, One
Hello Guice Binder For Constructor Two
Copy the code

We can use a @inject to achieve multiple parameter instance injection, of course, also support Set injection, just need to add @inject annotation on the parameter Set method to achieve, here we do not do more description, can experiment by ourselves.

Static Static parameter injection


We said that you can’t inject static directly. There are always many methods. Guice provides the following static injection methods.

In SRC/test/Java directory to create io.edu rt. Lc. Guice. TestGuiceStatic class files to define service test, add the following code

package io.edurt.lc.guice;

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

public class TestGuiceStatic
{
    @Inject
    private static GuiceConstructorService service;

    public static void main(String[] args)
    {
        Guice.createInjector(binder -> binder.requestStaticInjection(TestGuiceStatic.class));
        TestGuiceStatic.service.print("Static"); }}Copy the code

After running the program, output the following results

Hello Guice Binder For Constructor, Static
Copy the code

We don’t have in your code directly to the above two sample use Guice for instance, but use, is the binder. The requestStaticInjection way for injection, and this is the static attributes, which is closely linked When we inject a static property, we need to tell Guice that we are using the parent class of the static property so that Guice can inject it for us.

Carefully think about since we use binder. RequestStaticInjection way into static properties, so the static attributes can also be injected in a similar way?

For non-static properties, binder. RequestInjection (Type); The example is as follows:

In SRC/test/Java directory to create io.edu rt. Lc. Guice. TestGuiceNonStatic class files to define service test, add the following code

package io.edurt.lc.guice;

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

public class TestGuiceNonStatic
{
    @Inject
    private GuiceConstructorService service;

    public static void main(String[] args)
    {
        TestGuiceNonStatic applicationBinder = new TestGuiceNonStatic();
        Guice.createInjector(binder -> binder.requestInjection(applicationBinder));
        applicationBinder.service.print("Non Static"); }}Copy the code

After running the program, output the following results

Hello Guice Binder For Constructor, Non Static
Copy the code

Guice.createinjector ().injectMembers(new Object()); Mode injection.

Note that we need to create an instance of the main class to inject, which is not possible with testGuicenonStatic.class

The source address


GitHub