Skip to content

Commit

Permalink
ArC - document io.quarkus.arc.WithCaching
Browse files Browse the repository at this point in the history
- resolves quarkusio#17625
  • Loading branch information
mkouba committed Jun 3, 2021
1 parent 0641dc7 commit 4de5771
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions docs/src/main/asciidoc/cdi-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,65 @@ class NaiveLoggingInterceptor {

Other interceptors could be provided to log method invocations to different targets.

=== Caching the Result of Programmatic Lookup

In certain situations, it is practical to obtain a bean instance programmatically via an injected `javax.enterprise.inject.Instance` and `Instance.get()`.
However, according to the specification the `get()` method must identify the matching bean and obtain a contextual reference.
As a consequence, a new instance of a `@Dependent` bean is returned from each invocation of `get()`.
Moreover, this instance is a dependent object of the injected `Instance`.
This behavior is well-defined but it may lead to unexpected errors and memory leaks.
Therefore, Quarkus comes with the `io.quarkus.arc.WithCaching` annotation.
An injected `Instance` annotated with this annotation will cache the result of the `Instance#get()` operation.
The result is computed on the first call and the same value is returned for all subsequent calls, even for `@Dependent` beans.

[source,java]
----
class Producer {
AtomicLong nextLong = new AtomicLong();
AtomicInteger nextInt = new AtomicInteger();
@Dependent
@Produces
Integer produceInt() {
return nextInt.incrementAndGet();
}
@Dependent
@Produces
Long produceLong() {
return nextLong.incrementAndGet();
}
}
import io.quarkus.arc.WithCaching;
import javax.enterprise.inject.Instance;
class Consumer {
@Inject
Instance<Long> longInstance;
@WithCaching
@Inject
Instance<Integer> intInstance;
// this method should always return true
// Producer#produceInt() is only called once
boolean pingInt() {
return intInstance.get().equals(intInstance.get());
}
// this method should always return false
// Producer#produceLong() is called twice per each pingLong() invocation
boolean pingLong() {
return longInstance.get().equals(longInstance.get());
}
}
----

TIP: It is also possible to clear the cached value via `io.quarkus.arc.InjectableInstance.clearCache()`. In this case, you'll need to inject the Quarkus-specific `io.quarkus.arc.InjectableInstance` instead of `javax.enterprise.inject.Instance`.

[[build_time_apis]]
== Build Time Extensions

Expand Down

0 comments on commit 4de5771

Please sign in to comment.