Skip to content

Commit

Permalink
Merge pull request #17671 from mkouba/issue-17625
Browse files Browse the repository at this point in the history
ArC - document io.quarkus.arc.WithCaching
  • Loading branch information
mkouba authored Jun 4, 2021
2 parents 32a744e + 4d69505 commit 0384e81
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 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,62 @@ 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();
}
}
class Consumer {
@Inject
Instance<Long> longInstance;
@Inject
@WithCaching
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 0384e81

Please sign in to comment.