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