Skip to main content

Quick Start

In this tutorial we will create an Injector from multiple DI modules. We will then use the Injector to create an instance of some service. We will use the annotation-based approach to define modules as it is more readable.

Helper classes

For theis tutorial, we will need 2 helper classes. The DataSource class, which represents the source of some data, and the Service class which uses data obtained from the data source for some processing.

public static final class DataSource {
private final InetSocketAddress address;
private final String dbName;

@Inject
public DataSource(InetSocketAddress address, String dbName) {
this.address = address;
this.dbName = dbName;
}

public String queryData() {
System.out.printf("Querying %s:%s for data%n", address, dbName);
return "data";
}
}
public static final class Service {
private final DataSource dataSource;

public Service(DataSource dataSource) {
this.dataSource = dataSource;
}

public void process() {
String data = dataSource.queryData();
System.out.printf("Processing data: '%s'%n", data);
}
}
note

Notice the @Inject annotation on the DataSource constructor. It will be explained later.

Modules

We will define two different modules: one for the configuration and one for the service itself.

public static class ConfigModule extends AbstractModule {
@Provides
InetSocketAddress inetSocketAddress() {
return new InetSocketAddress(1234);
}

@Provides
String dbName() {
return "exampleDB";
}
}

The ConfigModule provides both the address for the DataSource and the name of the database.

public static class ServiceModule extends AbstractModule {
@Provides
Service service(DataSource dataSource) {
return new Service(dataSource);
}
}

ServiceModule provides only the Service itself, which requires instantiation of the DataSource.

Injector

An Injector is created from two previously defined modules. After that, an instance of Service is obtained from the injector.

public static void main(String[] args) {
Injector injector = Injector.of(new ConfigModule(), new ServiceModule());
Service service = injector.getInstance(Service.class);
service.process();
}

The Service requires DataSource instantiation, but we did not provide DataSource explicitly in any of the modules. Thanks to the @Inject annotation on the DataSource's constructor, injector automatically injected required dependencies and instantiated the DataSource.

The output of service.process() call is:

Querying 0.0.0.0/0.0.0.0:1234:exampleDB for data
Processing data: 'data'

You can find example sources on Github