Better document #result semantic

Commit 240f254 has introduced support for `java.util.Optional` in the
cache abstraction. If such type is present, the contained value is cached
if it is present.

This new feature slightly changed the semantic of `#result` that was
documented up till this commit as the "return value of the method
invocation". This is no longer true as `#result` for `Optional<T>`
refers to the `T` instance and not the `Optional` instance.

This commit clarifies both the javadoc and the documentation.

Issue: SPR-14587
master
Stephane Nicoll 8 years ago
parent c17c43a1fe
commit 0d59a15849
  1. 4
      spring-context/src/main/java/org/springframework/cache/annotation/CacheEvict.java
  2. 12
      spring-context/src/main/java/org/springframework/cache/annotation/CachePut.java
  3. 8
      spring-context/src/main/java/org/springframework/cache/annotation/Cacheable.java
  4. 15
      src/asciidoc/integration.adoc

@ -69,7 +69,9 @@ public @interface CacheEvict {
* following meta-data:
* <ul>
* <li>{@code #result} for a reference to the result of the method invocation, which
* can only be used if {@link #beforeInvocation()} is {@code false}.</li>
* can only be used if {@link #beforeInvocation()} is {@code false}. For supported
* wrappers such as {@code Optional}, {@code #result} refers to the actual object,
* not the wrapper</li>
* <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for
* references to the {@link java.lang.reflect.Method method}, target object, and
* affected cache(s) respectively.</li>

@ -31,7 +31,9 @@ import org.springframework.core.annotation.AliasFor;
*
* <p>In contrast to the {@link Cacheable @Cacheable} annotation, this annotation
* does not cause the advised method to be skipped. Rather, it always causes the
* method to be invoked and its result to be stored in the associated cache.
* method to be invoked and its result to be stored in the associated cache. Note
* that Java8's {@code Optional} return types are automatically handled and its
* content is stored in the cache if present.
*
* <p>This annotation may be used as a <em>meta-annotation</em> to create custom
* <em>composed annotations</em> with attribute overrides.
@ -73,7 +75,9 @@ public @interface CachePut {
* <p>The SpEL expression evaluates against a dedicated context that provides the
* following meta-data:
* <ul>
* <li>{@code #result} for a reference to the result of the method invocation.</li>
* <li>{@code #result} for a reference to the result of the method invocation. For
* supported wrappers such as {@code Optional}, {@code #result} refers to the actual
* object, not the wrapper</li>
* <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for
* references to the {@link java.lang.reflect.Method method}, target object, and
* affected cache(s) respectively.</li>
@ -138,7 +142,9 @@ public @interface CachePut {
* <p>The SpEL expression evaluates against a dedicated context that provides the
* following meta-data:
* <ul>
* <li>{@code #result} for a reference to the result of the method invocation.</li>
* <li>{@code #result} for a reference to the result of the method invocation. For
* supported wrappers such as {@code Optional}, {@code #result} refers to the actual
* object, not the wrapper</li>
* <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for
* references to the {@link java.lang.reflect.Method method}, target object, and
* affected cache(s) respectively.</li>

@ -38,7 +38,9 @@ import org.springframework.core.annotation.AliasFor;
* replace the default one (see {@link #keyGenerator}).
*
* <p>If no value is found in the cache for the computed key, the target method
* will be invoked and the returned value stored in the associated cache.
* will be invoked and the returned value stored in the associated cache. Note
* that Java8's {@code Optional} return types are automatically handled and its
* content is stored in the cache if present.
*
* <p>This annotation may be used as a <em>meta-annotation</em> to create custom
* <em>composed annotations</em> with attribute overrides.
@ -144,7 +146,9 @@ public @interface Cacheable {
* <p>The SpEL expression evaluates against a dedicated context that provides the
* following meta-data:
* <ul>
* <li>{@code #result} for a reference to the result of the method invocation.</li>
* <li>{@code #result} for a reference to the result of the method invocation. For
* supported wrappers such as {@code Optional}, {@code #result} refers to the actual
* object, not the wrapper</li>
* <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for
* references to the {@link java.lang.reflect.Method method}, target object, and
* affected cache(s) respectively.</li>

@ -8333,6 +8333,18 @@ only want to cache paperback books:
public Book findBook(String name)
----
The cache abstraction supports `java.util.Optional`, using its content as cached value
only if it present. `#result` always refers to the business entity and never on a
supported wrapper so the previous example can be rewritten as follows:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Cacheable(cacheNames="book", condition="#name.length < 32", **unless="#result.hardback"**)
public Optional<Book> findBook(String name)
----
Note that `result` still refers to `Book` and not `Optional`.
[[cache-spel-context]]
===== Available caching SpEL evaluation context
@ -8389,7 +8401,8 @@ conditional computations:
| evaluation context
| The result of the method call (the value to be cached). Only available in `unless`
expressions, `cache put` expressions (to compute the `key`), or `cache evict`
expressions (when `beforeInvocation` is `false`).
expressions (when `beforeInvocation` is `false`). For supported wrappers such as
`Optional`, `#result` refers to the actual object, not the wrapper.
| `#result`
|===

Loading…
Cancel
Save