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);
}
}
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