Browse Source

Improve cache abstraction chapter

This commit is a general update of the Cache Abstraction chapter.

Existing sections have been updated with recent improvements made in
that area, in particular:
* Guava and JSR-107 caches support
* New @CacheConfig annotation allowing to share some key customizations
  at class-level
* CacheResolver interface used to resolve the cache(s) to use at
  runtime
* Update section on @CachePut

This commit also describes the support of standard JCache annotations,
i.e. JSR-107.

Issues: SPR-11490, SPR-11316, SPR-10629, SPR-9616, SPR-8696
pull/512/head
Stephane Nicoll 12 years ago
parent
commit
2b89c1a87e
  1. 406
      src/asciidoc/index.adoc

406
src/asciidoc/index.adoc

@ -46089,6 +46089,8 @@ into an existing Spring application. Similar to the <<transaction,transaction>> @@ -46089,6 +46089,8 @@ into an existing Spring application. Similar to the <<transaction,transaction>>
the caching abstraction allows consistent use of various caching solutions with minimal
impact on the code.
As from Spring 4.1, the cache abstraction has been significantly improved with the
support of <<cache-jsr-107,JSR-107 annotations>> and more customization options.
@ -46132,29 +46134,41 @@ output (result) for a given input (or arguments) no matter how many times it is @@ -46132,29 +46134,41 @@ output (result) for a given input (or arguments) no matter how many times it is
executed.
====
To use the cache abstraction, the developer needs to take care of two aspects:
Other cache-related operations are provided by the abstraction such as the ability
to update the content of the cache or remove one of all entries. These are useful if
the cache deals with data that can change during the course of the application.
* caching declaration - identify the methods that need to be cached and their policy
* cache configuration - the backing cache where the data is stored and read from
Note that just like other services in Spring Framework, the caching service is an
Just like other services in the Spring Framework, the caching service is an
abstraction (not a cache implementation) and requires the use of an actual storage to
store the cache data - that is, the abstraction frees the developer from having to write
the caching logic but does not provide the actual stores. There are two integrations
available out of the box, for JDK `java.util.concurrent.ConcurrentMap` and
http://ehcache.org/[EhCache] - see <<cache-plug>> for more information on plugging in
the caching logic but does not provide the actual stores. This abstraction is
materialized by the `org.springframework.cache.Cache` and
`org.springframework.cache.CacheManager` interfaces.
There are <<cache-store-configuration,a few implementations>> of that abstraction
available out of the box: JDK `java.util.concurrent.ConcurrentMap` based caches,
http://ehcache.org/[EhCache], Gemfire cache,
https://code.google.com/p/guava-libraries/wiki/CachesExplained[Guava caches] and
JSR-107 compliant caches. See <<cache-plug>> for more information on plugging in
other cache stores/providers.
To use the cache abstraction, the developer needs to take care of two aspects:
* caching declaration - identify the methods that need to be cached and their policy
* cache configuration - the backing cache where the data is stored and read from
[[cache-annotations]]
=== Declarative annotation-based caching
For caching declaration, the abstraction provides two Java annotations: `@Cacheable` and
`@CacheEvict` which allow methods to trigger cache population or cache eviction. Let us
take a closer look at each annotation:
For caching declaration, the abstraction provides a set of Java annotations:
* `@Cacheable` triggers cache population
* `@CacheEvict` triggers cache eviction
* `@CachePut` updates the cache without interfering with the method execution
* `@Caching` regroups multiple cache operations to be applied on a method
* `@CacheConfig` shares some common cache-related settings at class-level
Let us take a closer look at each annotation:
[[cache-annotations-cacheable]]
==== @Cacheable annotation
@ -46176,20 +46190,20 @@ In the snippet above, the method `findBook` is associated with the cache named ` @@ -46176,20 +46190,20 @@ In the snippet above, the method `findBook` is associated with the cache named `
Each time the method is called, the cache is checked to see whether the invocation has
been already executed and does not have to be repeated. While in most cases, only one
cache is declared, the annotation allows multiple names to be specified so that more
then one cache are being used. In this case, each of the caches will be checked before
than one cache are being used. In this case, each of the caches will be checked before
executing the method - if at least one cache is hit, then the associated value will be
returned:
[NOTE]
====
All the other caches that do not contain the method will be updated as well even though
All the other caches that do not contain the value will be updated as well even though
the cached method was not actually executed.
====
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Cacheable({ "books", "isbns" })
@Cacheable({"books", "isbns"})
public Book findBook(ISBN isbn) {...}
----
@ -46205,13 +46219,11 @@ abstraction uses a simple `KeyGenerator` based on the following algorithm: @@ -46205,13 +46219,11 @@ abstraction uses a simple `KeyGenerator` based on the following algorithm:
* If more the one param is given, return a `SimpleKey` containing all parameters.
This approach works well for most use-cases; As long as parameters have __natural keys__
and implement valid `hashCode()` and `equals()` methods. If that is not the case the the
and implement valid `hashCode()` and `equals()` methods. If that is not the case then the
strategy needs to be changed.
To provide a different __default__ key generator, one needs to implement the
`org.springframework.cache.KeyGenerator` interface. Once configured, the generator will
be used for each declaration that does not specify its own key generation strategy (see
below).
`org.springframework.cache.interceptor.KeyGenerator` interface.
[NOTE]
@ -46251,7 +46263,7 @@ generated through its `key` attribute. The developer can use <<expressions,SpEL> @@ -46251,7 +46263,7 @@ generated through its `key` attribute. The developer can use <<expressions,SpEL>
pick the arguments of interest (or their nested properties), perform operations or even
invoke arbitrary methods without having to write any code or implement any interface.
This is the recommended approach over the
<<cache-annotations-cacheable-default-key,default>> generator since methods tend to be
<<cache-annotations-cacheable-default-key,default generator>> since methods tend to be
quite different in signatures as the code base grows; while the default strategy might
work for some methods, it rarely does for all methods.
@ -46274,6 +46286,75 @@ do yourself a favor and read <<expressions>>: @@ -46274,6 +46286,75 @@ do yourself a favor and read <<expressions>>:
The snippets above show how easy it is to select a certain argument, one of its
properties or even an arbitrary (static) method.
If the algorithm responsible to generate the key is too specific or if it needs
to be shared, you may define a custom `keyGenerator` on the operation. To do
this, specify the name of the `KeyGenerator` bean implementation to use:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Cacheable(value="books", **keyGenerator="myKeyGenerator"**)
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
----
[NOTE]
====
The `key` and `keyGenerator` parameters are mutually exclusive and an operation
specifying both will result in an exception.
====
[[cache-annotations-cacheable-default-cache-resolver]]
===== Default Cache Resolution
Out of the box, the caching abstraction uses a simple `CacheResolver` that
retrieves the cache(s) defined at the operation level using the configured
`CacheManager`.
To provide a different __default__ cache resolver, one needs to implement the
`org.springframework.cache.interceptor.CacheResolver` interface.
[[cache-annotations-cacheable-cache-resolver]]
===== Custom cache resolution
The default cache resolution fits well for applications working with a
single `CacheManager` and with no complex cache resolution requirements.
For applications working with several cache managers, it is possible
to set the `cacheManager` to use per operation:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Cacheable(value="books", **cacheManager="anotherCacheManager"**)
public Book findBook(ISBN isbn) {...}
----
It is also possible to replace the `CacheResolver` entirely in a similar
fashion as for <<cache-annotations-cacheable-key,key generation>>. The
resolution is requested for every cache operation, giving a chance to
the implementation to actually resolve the cache(s) to use based on
runtime arguments:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Cacheable(**cacheResolver="runtimeCacheResolver"**)
public Book findBook(ISBN isbn) {...}
----
[NOTE]
====
Since Spring 4.1, the `value` attribute of the cache annotations are no longer
mandatory since this particular information can be provided by the `CacheResolver`
regardless of the content of the annotation.
Similarly to `key` and `keyGenerator`, the `cacheManager` and `cacheResolver`
parameters are mutually exclusive and an operation specifying both will
result in an exception as a custom `CacheManager` will be ignored by the
`CacheResolver` implementation. This is probably not what you expect.
====
[[cache-annotations-cacheable-condition]]
===== Conditional caching
@ -46288,7 +46369,7 @@ only if the argument `name` has a length shorter than 32: @@ -46288,7 +46369,7 @@ only if the argument `name` has a length shorter than 32:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Cacheable(value="book", condition="#name.length < 32")
@Cacheable(value="book", **condition="#name.length < 32"**)
public Book findBook(String name)
----
@ -46300,7 +46381,7 @@ only want to cache paperback books: @@ -46300,7 +46381,7 @@ only want to cache paperback books:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Cacheable(value="book", condition="#name.length < 32", unless="#result.hardback")
@Cacheable(value="book", condition="#name.length < 32", **unless="#result.hardback"**)
public Book findBook(String name)
----
@ -46312,7 +46393,7 @@ Each `SpEL` expression evaluates again a dedicated @@ -46312,7 +46393,7 @@ Each `SpEL` expression evaluates again a dedicated
<<expressions-language-ref,`context`>>. In addition to the build in parameters, the
framework provides dedicated caching related metadata such as the argument names. The
next table lists the items made available to the context so one can use them for key and
conditional (see next section) computations:
conditional computations:
[[cache-spel-context-tbl]]
.Cache SpEL available metadata
@ -46364,7 +46445,6 @@ conditional (see next section) computations: @@ -46364,7 +46445,6 @@ conditional (see next section) computations:
|===
[[cache-annotations-put]]
==== @CachePut annotation
@ -46372,15 +46452,25 @@ For cases where the cache needs to be updated without interfering with the metho @@ -46372,15 +46452,25 @@ For cases where the cache needs to be updated without interfering with the metho
execution, one can use the `@CachePut` annotation. That is, the method will always be
executed and its result placed into the cache (according to the `@CachePut` options). It
supports the same options as `@Cacheable` and should be used for cache population rather
then method flow optimization.
than method flow optimization:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@CachePut(value="book", key="#isbn")
public Book updateBook(ISBN isbn, BookDescriptor descriptor)
----
[IMPORTANT]
====
Note that using `@CachePut` and `@Cacheable` annotations on the same method is generally
discouraged because they have different behaviors. While the latter causes the method
execution to be skipped by using the cache, the former forces the execution in order to
execute a cache update. This leads to unexpected behavior and with the exception of
specific corner-cases (such as annotations having conditions that exclude them from each
other), such declarations should be avoided.
====
[[cache-annotations-evict]]
@ -46391,20 +46481,21 @@ This process is useful for removing stale or unused data from the cache. Opposed @@ -46391,20 +46481,21 @@ This process is useful for removing stale or unused data from the cache. Opposed
`@Cacheable`, annotation `@CacheEvict` demarcates methods that perform cache
__eviction__, that is methods that act as triggers for removing data from the cache.
Just like its sibling, `@CacheEvict` requires specifying one (or multiple) caches
that are affected by the action, allows a key or a condition to be specified but in
addition, features an extra parameter `allEntries` which indicates whether a cache-wide
eviction needs to be performed rather then just an entry one (based on the key):
that are affected by the action, allows a custom cache and key resolution or a
condition to be specified but in addition, features an extra parameter
`allEntries` which indicates whether a cache-wide eviction needs to be performed
rather then just an entry one (based on the key):
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@CacheEvict(value = "books", allEntries=true)
@CacheEvict(value="books", **allEntries=true**)
public void loadBooks(InputStream batch)
----
This option comes in handy when an entire cache region needs to be cleared out - rather
then evicting each entry (which would take a long time since it is inefficient), all the
entires are removed in one operation as shown above. Note that the framework will ignore
entries are removed in one operation as shown above. Note that the framework will ignore
any key specified in this scenario as it does not apply (the entire cache is evicted not
just one entry).
@ -46437,18 +46528,49 @@ this case, `@Caching`. `@Caching` allows multiple nested `@Cacheable`, `@CachePu @@ -46437,18 +46528,49 @@ this case, `@Caching`. `@Caching` allows multiple nested `@Cacheable`, `@CachePu
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value="secondary", key="#p0") })
public Book importBooks(String deposit, Date date)
----
[[cache-annotations-config]]
==== @CacheConfig annotation
So far we have seen that caching operations offered many customization options and
these can be set on an operation basis. However, some of the customization options
can be tedious to configure if they apply to all operations of the class. For
instance, specifying the name of the cache to use for every cache operation of the
class could be replaced by a single class-level definition. This is where `@CacheConfig`
comes into play.
[source,java,indent=0]
[subs="verbatim,quotes"]
----
**@CacheConfig("books")**
public class BookRepositoryImpl implements BookRepository {
@Cacheable
public Book findBook(ISBN isbn) {...}
}
----
`@CacheConfig` is a class-level annotation that allows to share the cache names, the custom
`KeyGenerator`, the custom `CacheManager` and finally the custom `CacheResolver`. Placing
this annotation on the class does not turn on any caching operation.
An operation-level customization will always override a customization set on `@CacheConfig`. This
gives therefore three levels of customizations per cache operation:
* Globally configured, available for `CacheManager`, `KeyGenerator`
* At class level, using `@CacheConfig`
* At the operation level
[[cache-annotation-enable]]
==== Enable caching annotations
It is important to note that even though declaring the cache annotations does not
automatically trigger their actions - like many things in Spring, the feature has to be
declaratively enabled (which means if you ever suspect caching is to blame, you can
disable it by removing only one configuration line rather then all the annotations in
disable it by removing only one configuration line rather than all the annotations in
your code).
To enable caching annotations add the annotation `@EnableCaching` to one of your
@ -46495,7 +46617,7 @@ application through AOP. The configuration is intentionally similar with that of @@ -46495,7 +46617,7 @@ application through AOP. The configuration is intentionally similar with that of
| N/A (See `CachingConfigurer` javadocs)
| cacheManager
| Name of cache manager to use. Only required if the name of the cache manager is not
`cacheManager`, as in the example above.
`cacheManager`.
| `mode`
| `mode`
@ -46529,16 +46651,16 @@ application through AOP. The configuration is intentionally similar with that of @@ -46529,16 +46651,16 @@ application through AOP. The configuration is intentionally similar with that of
[NOTE]
====
`<cache:annotation-driven/>` only looks for `@Cacheable/@CacheEvict` on beans in the
same application context it is defined in. This means that, if you put
`<cache:annotation-driven/>` only looks for `@Cacheable/@CachePut/@CacheEvict/@Caching`
on beans in the same application context it is defined in. This means that, if you put
`<cache:annotation-driven/>` in a `WebApplicationContext` for a `DispatcherServlet`, it
only checks for `@Cacheable/@CacheEvict` beans in your controllers, and not your
services. See <<mvc-servlet>> for more information.
only checks for beans in your controllers, and not your services. See <<mvc-servlet>>
for more information.
====
.Method visibility and @Cacheable / @CachePut / @CacheEvict
.Method visibility and cache annotations
****
When using proxies, you should apply the `@Cache*` annotations only to methods with
When using proxies, you should apply the cache annotations only to methods with
__public__ visibility. If you do annotate protected, private or package-visible methods
with these annotations, no error is raised, but the annotated method does not exhibit
the configured caching settings. Consider the use of AspectJ (see below) if you need to
@ -46572,13 +46694,13 @@ using the aspectj mode in this case. @@ -46572,13 +46694,13 @@ using the aspectj mode in this case.
[[cache-annotation-stereotype]]
==== Using custom annotations
The caching abstraction allows you to use your own annotations to identify what method
trigger cache population or eviction. This is quite handy as a template mechanism as it
triggers cache population or eviction. This is quite handy as a template mechanism as it
eliminates the need to duplicate cache annotation declarations (especially useful if the
key or condition are specified) or if the foreign imports (`org.springframework`) are
not allowed in your code base. Similar to the rest of the
<<beans-stereotype-annotations,stereotype>> annotations, both `@Cacheable` and
`@CacheEvict` can be used as <<beans-meta-annotations,meta-annotations>>, that is
annotations that can annotate other annotations. To wit, let us replace a common
<<beans-stereotype-annotations,stereotype>> annotations, `@Cacheable`, `@CachePut`,
`@CacheEvict` and `@CacheConfig` can be used as <<beans-meta-annotations,meta-annotations>>,
that is annotations that can annotate other annotations. To wit, let us replace a common
`@Cacheable` declaration with our own, custom annotation:
[source,java,indent=0]
@ -46615,6 +46737,133 @@ up its declaration at runtime and understands its meaning. Note that as mentione @@ -46615,6 +46737,133 @@ up its declaration at runtime and understands its meaning. Note that as mentione
<<cache-annotation-enable,above>>, the annotation-driven behavior needs to be enabled.
[[cache-jsr-107]]
=== JCache (JSR-107) annotations
Since the Spring Framework 4.1, the caching abstraction fully supports the JCache
standard annotations: these are `@CacheResult`, `@CacheEvict`, `@CacheRemove` and
`@CacheRemoveAll` as well as the `@CachingDefaults`, `@CacheKey` and `@CacheValue`
companions. These annotations can be used right the way without migrating your
cache store to JSR-107: the internal implementation uses Spring's caching abstraction
and provides default `CacheResolver` and `KeyGenerator` implementations that are
compliant with the specification. In other words, if you are already using Spring's
caching abstraction, you can switch to these standard annotations without changing
your cache storage (or configuration, for that matter).
[[cache-jsr-107-summary]]
==== Features summary
For those who are familiar with Spring's caching annotations, the following table
describes the main differences between the Spring annotations and the JSR-107
counterpart:
.Spring vs. JSR-107 caching annotations
[cols="1,1,3"]
|===
| Spring| JSR-107| Remark
| `@Cacheable`
| `@CacheResult`
| Fairly similar. `@CacheResult` can cache specific exceptions and force the
execution of the method regardless of the content of the cache.
| `@CachePut`
| `@CachePut`
| While Spring updates the cache with the result of the method invocation, JCache
requires to pass it as an argument that is annotated with `@CacheValue`. Due
to this difference, JCache allows to update the cache before or after the
actual method invocation.
| `@CacheEvict`
| `@CacheRemove`
| Fairly similar. `@CacheRemove` supports a conditional evict in case the
method invocation results in an exception.
| `@CacheEvict(allEntries=true)`
| `@CacheRemoveAll`
| See `@CacheRemove`.
| `@CacheConfig`
| `@CacheDefaults`
| Allows to configure the same concepts, in a similar fashion.
|===
JCache has the notion of `javax.cache.annotation.CacheResolver` that is identical
to the Spring's `CacheResolver` interface, except that JCache only supports a single
cache. By default, a simple implementation retrieves the cache to use based on
the name declared on the annotation. It should be noted that if no cache name
is specified on the annotation, a default is automatically generated, check the
javadoc of `@CacheResult#cacheName()` for more information.
`CacheResolver` instances are retrieved by a `CacheResolverFactory`. It is
possible to customize the factory per cache operation:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@CacheResult(value="books", *cacheResolverFactory=MyCacheResolverFactory.class*)
public Book findBook(ISBN isbn)
----
[NOTE]
====
For all referenced _classes_, Spring tries to locate a bean with the given type. If
more than one match exists, a new instance is created and can use the regular
bean lifecycle callbacks such as dependency injection.
====
Keys are generated by a `javax.cache.annotation.CacheKeyGenerator` that serves the
same purpose as Spring's `KeyGenerator`. By default, all method arguments are taken
into account unless at least one parameter is annotated with `@CacheKey`. This is
similar to Spring's <<cache-annotations-cacheable-key,custom key generation
declaration>>. For instance these are identical operations, one using Spring's
abstraction and the other with JCache:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Cacheable(value="books", **key="#isbn"**)
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
@CacheResult(cacheName="books")
public Book findBook(**@CacheKey** ISBN isbn, boolean checkWarehouse, boolean includeUsed)
----
The `CacheKeyResolver` to use can also be specified on the operation, in a similar
fashion as the `CacheResolverFactory`.
JCache can manage exceptions thrown by annotated methods: this can prevent an update of
the cache but it can also cache the exception as an indicator of the failure instead of
calling the method again. Let's assume that `InvalidIsbnNotFoundException` is thrown if
the structure of the ISBN is invalid. This is a permanent failure, no book could ever be
retrieved with such parameter. The following caches the exception so that further calls
with the same, invalid ISBN, returns the cached exception directly instead of invoking
the method again.
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@CacheResult(cacheName="books", **exceptionCacheName="failures"**
**cachedExceptions = InvalidIsbnNotFoundException.class**)
public Book findBook(@CacheKey ISBN isbn)
----
==== Enabling JSR-107 support
Nothing specific needs to be done to enable the JSR-107 support alongside Spring's
declarative annotation support. Both `@EnableCaching` and the
`cache:annotation-driven` element will enable automatically the JCache support
if both the JSR-107 API and the `spring-context-support` module are present in
the classpath.
[NOTE]
====
Depending of your use case, the choice is basically yours. You can even mix
and match services using the JSR-107 API and others using Spring's own
annotations. Be aware however that if these services are impacting the same
caches, a consistent and identical key generation implementation should be used.
====
[[cache-declarative-xml]]
@ -46674,13 +46923,11 @@ we did in the example above by defining the target cache through the `cache:defi @@ -46674,13 +46923,11 @@ we did in the example above by defining the target cache through the `cache:defi
[[cache-store-configuration]]
=== Configuring the cache storage
Out of the box, the cache abstraction provides integration with two storages - one on
top of the JDK `ConcurrentMap` and one for http://ehcache.org/[EhCache] library. To use
Out of the box, the cache abstraction provides several storages integration. To use
them, one needs to simply declare an appropriate `CacheManager` - an entity that
controls and manages ++Cache++s and can be used to retrieve these for storage.
[[cache-store-configuration-jdk]]
==== JDK ConcurrentMap-based Cache
@ -46691,7 +46938,7 @@ as a backing `Cache` store. @@ -46691,7 +46938,7 @@ as a backing `Cache` store.
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<!-- generic cache manager -->
<!-- simple cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
@ -46722,17 +46969,52 @@ Again, to use it, one simply needs to declare the appropriate `CacheManager`: @@ -46722,17 +46969,52 @@ Again, to use it, one simply needs to declare the appropriate `CacheManager`:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache"/>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache"/>
<!-- EhCache library setup -->
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="ehcache.xml"/>
<bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="ehcache.xml"/>
----
This setup bootstraps ehcache library inside Spring IoC (through bean `ehcache`) which
This setup bootstraps the ehcache library inside Spring IoC (through the `ehcache` bean) which
is then wired into the dedicated `CacheManager` implementation. Note the entire
ehcache-specific configuration is read from the resource `ehcache.xml`.
ehcache-specific configuration is read from `ehcache.xml`.
[[cache-store-configuration-guava]]
==== Guava Cache
The Guava implementation is located under `org.springframework.cache.guava` package and
provides access to several features of Guava.
Configuring a `CacheManager` that creates the cache on demand is straightforward:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<bean id="cacheManager"
class="org.springframework.cache.guava.GuavaCacheManager"/>
----
It is also possible to provide the caches to use explicitly. In that case, only those
will be made available by the manager:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<bean id="cacheManager" class="org.springframework.cache.guava.GuavaCacheManager">
<property name="caches">
<set>
<value>default</value>
<value>books</value>
</set>
</property>
</bean>
----
The Guava `CacheManager` also supports customs `CacheBuilder` and `CacheLoader`. See
the https://code.google.com/p/guava-libraries/wiki/CachesExplained[Guava documentation]
for more information about those.
[[cache-store-configuration-gemfire]]
==== GemFire-based Cache
@ -46741,9 +47023,27 @@ GemFire is a memory-oriented/disk-backed, elastically scalable, continuously ava @@ -46741,9 +47023,27 @@ GemFire is a memory-oriented/disk-backed, elastically scalable, continuously ava
active (with built-in pattern-based subscription notifications), globally replicated
database and provides fully-featured edge caching. For further information on how to use
GemFire as a CacheManager (and more), please refer to the
http://docs.spring.io/spring-gemfire/docs/current/reference/htmlsingle/[Spring GemFire
http://docs.spring.io/spring-gemfire/docs/current/reference/htmlsingle/[Spring Data GemFire
reference documentation].
[[cache-store-configuration-jsr107]]
==== JSR-107 Cache
JSR-107 compliant caches can also be used by Spring's caching abstraction. The JCache
implementation is located under `org.springframework.cache.jcache` package.
Again, to use it, one simply needs to declare the appropriate `CacheManager`:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<bean id="cacheManager"
class="org.springframework.cache.jcache.JCacheCacheManager"
p:cache-manager-ref="jCacheManager"/>
<!-- JSR-107 cache manager setup -->
<bean id="jCacheManager" .../>
----
[[cache-store-configuration-noop]]
@ -46784,7 +47084,7 @@ method to be executed every time. @@ -46784,7 +47084,7 @@ method to be executed every time.
Clearly there are plenty of caching products out there that can be used as a backing
store. To plug them in, one needs to provide a `CacheManager` and `Cache` implementation
since unfortunately there is no available standard that we can use instead. This may
sound harder then it is since in practice, the classes tend to be simple
sound harder than it is since in practice, the classes tend to be simple
http://en.wikipedia.org/wiki/Adapter_pattern[adapter]s that map the caching abstraction
framework on top of the storage API as the `ehcache` classes can show. Most
`CacheManager` classes can use the classes in `org.springframework.cache.support`

Loading…
Cancel
Save