Transient bindings
By default, every instance obtained using ActiveJ Inject is a singleton. This means that instances are cached the first time
they are retrieved and then reused in subsequent Injector#getInstance
calls. This behavior is different from the default
behaviour of most other dependency injection frameworks.
However, there are situations when you do not want to cache an instance, but rather you want to create a new instance each time. For that, you can use "transient" binding. Such bindings are special in that instances obtained with "transient" bindings are not cached. Such instances are recreated each time they are retrieved.
Transient bindings are not transitive. If you have a non-transient binding A
that depends on an instance
provided through a transient binding B
, a binding A
is not itself transient. It will use a cached instance of the transient
binding.
Defining transient bindings
There are several ways to define a transient binding.
We can use the asTransient()
method from the ModuleBuilder DSL
and mark a binding as transient as follows:
bind(double.class).to(Math::random).asTransient();
Or, alternatively we can use the @Transient
annotation to annotate methods already annotated with the @Provides
annotation:
@Provides
double random() {
return Math.random();
}
When you retrieve an instance of double
from the injector, you will get a new random number each time.
Transient binding example
Let's look at another example. Imagine that our application needs to know a current time. Therefore, we cannot cache an
Instant
instance. Therefore, we have to create a binding for an Instant
as a transient binding.
Let's define a module that defines a binding for an instance of current Instant
(notice the @Transient
annotation):
static class CurrentTimeModule extends AbstractModule {
@Provides
@Transient
Instant currentInstant() {
return Instant.now();
}
}
Now let's retrieve two instances of an Instant
from the injector, waiting for a second between each retrieval:
Injector injector = Injector.of(new CurrentTimeModule());
System.out.println(injector.getInstance(Instant.class));
Thread.sleep(1000);
System.out.println(injector.getInstance(Instant.class));
If we run the example, we see that the retrieved instances of Instant
differ by about 1 second.
You can find a full example on Github