Skip to main content

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.

note

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