Normalize whitespace in cache reference doc
This commit is contained in:
parent
41c405998e
commit
02cd8681d4
|
|
@ -3,18 +3,18 @@
|
||||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||||
|
|
||||||
<chapter id="cache">
|
<chapter id="cache">
|
||||||
<title>Cache Abstraction</title>
|
<title>Cache Abstraction</title>
|
||||||
|
|
||||||
<section id="cache-introduction">
|
<section id="cache-introduction">
|
||||||
<title>Introduction</title>
|
<title>Introduction</title>
|
||||||
|
|
||||||
<para>Since version 3.1, Spring Framework provides support for transparently
|
<para>Since version 3.1, Spring Framework provides support for transparently
|
||||||
adding caching into an existing Spring application. Similar to the <link linkend="transaction">transaction</link>
|
adding caching into an existing Spring application. Similar to the <link linkend="transaction">transaction</link>
|
||||||
support, the caching abstraction allows consistent use of various caching
|
support, the caching abstraction allows consistent use of various caching
|
||||||
solutions with minimal impact on the code.</para>
|
solutions with minimal impact on the code.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="cache-strategies">
|
<section id="cache-strategies">
|
||||||
<title>Understanding the cache abstraction</title>
|
<title>Understanding the cache abstraction</title>
|
||||||
|
|
||||||
<sidebar>
|
<sidebar>
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
A buffer is used traditionally as an intermediate temporary store for data between a fast and a slow entity. As one
|
A buffer is used traditionally as an intermediate temporary store for data between a fast and a slow entity. As one
|
||||||
party would have to <emphasis>wait</emphasis> for the other affecting performance, the buffer alleviates this by
|
party would have to <emphasis>wait</emphasis> for the other affecting performance, the buffer alleviates this by
|
||||||
allowing entire blocks of data to move at once rather then in small chunks. The data is written and read only once from
|
allowing entire blocks of data to move at once rather then in small chunks. The data is written and read only once from
|
||||||
the buffer. Further more, the buffers are <emphasis>visible</emphasis> to at least one party which is aware of it.</para>
|
the buffer. Furthermore, the buffers are <emphasis>visible</emphasis> to at least one party which is aware of it.</para>
|
||||||
<para>A cache on the other hand by definition is hidden and neither party is aware that caching occurs.It as well improves
|
<para>A cache on the other hand by definition is hidden and neither party is aware that caching occurs.It as well improves
|
||||||
performance but does that by allowing the same data to be read multiple times in a fast fashion.</para>
|
performance but does that by allowing the same data to be read multiple times in a fast fashion.</para>
|
||||||
|
|
||||||
|
|
@ -54,9 +54,9 @@
|
||||||
the use of an actual storage to store the cache data - that is, the abstraction frees the developer from having to write the caching
|
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 <literal>java.util.concurrent.ConcurrentMap</literal>
|
logic but does not provide the actual stores. There are two integrations available out of the box, for JDK <literal>java.util.concurrent.ConcurrentMap</literal>
|
||||||
and <ulink url="http://ehcache.org/">Ehcache</ulink> - see <xref linkend="cache-plug"/> for more information on plugging in other cache stores/providers.</para>
|
and <ulink url="http://ehcache.org/">Ehcache</ulink> - see <xref linkend="cache-plug"/> for more information on plugging in other cache stores/providers.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="cache-annotations">
|
<section id="cache-annotations">
|
||||||
<title>Declarative annotation-based caching</title>
|
<title>Declarative annotation-based caching</title>
|
||||||
|
|
||||||
<para>For caching declaration, the abstraction provides two Java annotations: <literal>@Cacheable</literal> and <literal>@CacheEvict</literal> which allow methods
|
<para>For caching declaration, the abstraction provides two Java annotations: <literal>@Cacheable</literal> and <literal>@CacheEvict</literal> which allow methods
|
||||||
|
|
@ -88,9 +88,9 @@ public Book findBook(ISBN isbn) {...}]]></programlisting>
|
||||||
<para>Since caches are essentially key-value stores, each invocation of a cached method needs to be translated into a suitable key for cache access.
|
<para>Since caches are essentially key-value stores, each invocation of a cached method needs to be translated into a suitable key for cache access.
|
||||||
Out of the box, the caching abstraction uses a simple <interfacename>KeyGenerator</interfacename> based on the following algorithm:</para>
|
Out of the box, the caching abstraction uses a simple <interfacename>KeyGenerator</interfacename> based on the following algorithm:</para>
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>If no params are given, return 0.</listitem>
|
<listitem>If no params are given, return 0.</listitem>
|
||||||
<listitem>If only one param is given, return that instance.</listitem>
|
<listitem>If only one param is given, return that instance.</listitem>
|
||||||
<listitem>If more the one param is given, return a key computed from the hashes of all parameters.</listitem>
|
<listitem>If more the one param is given, return a key computed from the hashes of all parameters.</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
<para>
|
<para>
|
||||||
This approach works well for objects with <emphasis>natural keys</emphasis> as long as the <literal>hashCode()</literal> reflects that. If that is not the case then
|
This approach works well for objects with <emphasis>natural keys</emphasis> as long as the <literal>hashCode()</literal> reflects that. If that is not the case then
|
||||||
|
|
@ -157,63 +157,63 @@ public Book findBook(String name)]]></programlisting>
|
||||||
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
|
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:</para>
|
so one can use them for key and conditional(see next section) computations:</para>
|
||||||
|
|
||||||
<table id="cache-spel-context-tbl" pgwide="1">
|
<table id="cache-spel-context-tbl" pgwide="1">
|
||||||
<title>Cache SpEL available metadata</title>
|
<title>Cache SpEL available metadata</title>
|
||||||
<tgroup cols="4">
|
<tgroup cols="4">
|
||||||
<colspec align="center" />
|
<colspec align="center" />
|
||||||
<thead>
|
<thead>
|
||||||
<row>
|
<row>
|
||||||
<entry>Name</entry>
|
<entry>Name</entry>
|
||||||
<entry>Location</entry>
|
<entry>Location</entry>
|
||||||
<entry>Description</entry>
|
<entry>Description</entry>
|
||||||
<entry>Example</entry>
|
<entry>Example</entry>
|
||||||
</row>
|
</row>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
<entry>methodName</entry>
|
<entry>methodName</entry>
|
||||||
<entry>root object</entry>
|
<entry>root object</entry>
|
||||||
<entry>The name of the method being invoked</entry>
|
<entry>The name of the method being invoked</entry>
|
||||||
<entry><screen>#root.methodName</screen></entry>
|
<entry><screen>#root.methodName</screen></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>method</entry>
|
<entry>method</entry>
|
||||||
<entry>root object</entry>
|
<entry>root object</entry>
|
||||||
<entry>The method being invoked</entry>
|
<entry>The method being invoked</entry>
|
||||||
<entry><screen>#root.method.name</screen></entry>
|
<entry><screen>#root.method.name</screen></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>target</entry>
|
<entry>target</entry>
|
||||||
<entry>root object</entry>
|
<entry>root object</entry>
|
||||||
<entry>The target object being invoked</entry>
|
<entry>The target object being invoked</entry>
|
||||||
<entry><screen>#root.target</screen></entry>
|
<entry><screen>#root.target</screen></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>targetClass</entry>
|
<entry>targetClass</entry>
|
||||||
<entry>root object</entry>
|
<entry>root object</entry>
|
||||||
<entry>The class of the target being invoked</entry>
|
<entry>The class of the target being invoked</entry>
|
||||||
<entry><screen>#root.targetClass</screen></entry>
|
<entry><screen>#root.targetClass</screen></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>params</entry>
|
<entry>params</entry>
|
||||||
<entry>root object</entry>
|
<entry>root object</entry>
|
||||||
<entry>The arguments (as array) used for invoking the target</entry>
|
<entry>The arguments (as array) used for invoking the target</entry>
|
||||||
<entry><screen>#root.params[0]</screen></entry>
|
<entry><screen>#root.params[0]</screen></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>caches</entry>
|
<entry>caches</entry>
|
||||||
<entry>root object</entry>
|
<entry>root object</entry>
|
||||||
<entry>Collection of caches against which the current method is executed</entry>
|
<entry>Collection of caches against which the current method is executed</entry>
|
||||||
<entry><screen>#root.caches[0].name</screen></entry>
|
<entry><screen>#root.caches[0].name</screen></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><emphasis>parameter name</emphasis></entry>
|
<entry><emphasis>parameter name</emphasis></entry>
|
||||||
<entry>evaluation context</entry>
|
<entry>evaluation context</entry>
|
||||||
<entry>Name of any of the method parameter. If for some reason the names are not available (ex: no debug information),
|
<entry>Name of any of the method parameter. If for some reason the names are not available (ex: no debug information),
|
||||||
the parameter names are also available under the <literal><![CDATA[p<#arg>]]></literal> where
|
the parameter names are also available under the <literal><![CDATA[p<#arg>]]></literal> where
|
||||||
<emphasis><![CDATA[#arg]]></emphasis> stands for the parameter index (starting from 0).</entry>
|
<emphasis><![CDATA[#arg]]></emphasis> stands for the parameter index (starting from 0).</entry>
|
||||||
<entry><screen>iban</screen> or <screen>p0</screen></entry>
|
<entry><screen>iban</screen> or <screen>p0</screen></entry>
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
|
@ -277,147 +277,147 @@ public Book importBooks(String deposit, Date date)]]></programlisting>
|
||||||
translates to one line that informs Spring that it should process the cache annotations, namely:</para>
|
translates to one line that informs Spring that it should process the cache annotations, namely:</para>
|
||||||
|
|
||||||
<programlisting language="xml"><![CDATA[<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"]]>
|
<programlisting language="xml"><![CDATA[<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"]]>
|
||||||
<emphasis role="bold">xmlns:cache="http://www.springframework.org/schema/cache"</emphasis><![CDATA[
|
<emphasis role="bold">xmlns:cache="http://www.springframework.org/schema/cache"</emphasis><![CDATA[
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd]]>
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd]]>
|
||||||
<emphasis role="bold">http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd</emphasis><![CDATA[">]]>
|
<emphasis role="bold">http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd</emphasis><![CDATA[">]]>
|
||||||
<emphasis role="bold"><![CDATA[<cache:annotation-driven />]]></emphasis>
|
<emphasis role="bold"><![CDATA[<cache:annotation-driven />]]></emphasis>
|
||||||
<![CDATA[</beans>]]></programlisting>
|
<![CDATA[</beans>]]></programlisting>
|
||||||
|
|
||||||
<para>The namespace allows various options to be specified that influence the way the caching behaviour is added to the application through AOP. The configuration is similar (on purpose)
|
<para>The namespace allows various options to be specified that influence the way the caching behaviour is added to the application through AOP. The configuration is similar (on purpose)
|
||||||
with that of <literal><ulink url="tx-annotation-driven-settings">tx:annotation-driven</ulink></literal>:
|
with that of <literal><ulink url="tx-annotation-driven-settings">tx:annotation-driven</ulink></literal>:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para><table id="cache-annotation-driven-settings">
|
<para><table id="cache-annotation-driven-settings">
|
||||||
<title><literal><cache:annotation-driven/></literal>
|
<title><literal><cache:annotation-driven/></literal>
|
||||||
settings</title>
|
settings</title>
|
||||||
|
|
||||||
<tgroup cols="3">
|
<tgroup cols="3">
|
||||||
<thead>
|
<thead>
|
||||||
<row>
|
<row>
|
||||||
<entry>Attribute</entry>
|
<entry>Attribute</entry>
|
||||||
|
|
||||||
<entry>Default</entry>
|
<entry>Default</entry>
|
||||||
|
|
||||||
<entry>Description</entry>
|
<entry>Description</entry>
|
||||||
</row>
|
</row>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>cache-manager</literal></entry>
|
<entry><literal>cache-manager</literal></entry>
|
||||||
|
|
||||||
<entry>cacheManager</entry>
|
<entry>cacheManager</entry>
|
||||||
|
|
||||||
<entry><para>Name of cache manager to use. Only required
|
<entry><para>Name of cache manager to use. Only required
|
||||||
if the name of the cache manager is not
|
if the name of the cache manager is not
|
||||||
<literal>cacheManager</literal>, as in the example
|
<literal>cacheManager</literal>, as in the example
|
||||||
above.</para></entry>
|
above.</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>mode</literal></entry>
|
<entry><literal>mode</literal></entry>
|
||||||
|
|
||||||
<entry>proxy</entry>
|
<entry>proxy</entry>
|
||||||
|
|
||||||
<entry><para>The default mode "proxy" processes annotated
|
<entry><para>The default mode "proxy" processes annotated
|
||||||
beans to be proxied using Spring's AOP framework (following
|
beans to be proxied using Spring's AOP framework (following
|
||||||
proxy semantics, as discussed above, applying to method calls
|
proxy semantics, as discussed above, applying to method calls
|
||||||
coming in through the proxy only). The alternative mode
|
coming in through the proxy only). The alternative mode
|
||||||
"aspectj" instead weaves the affected classes with Spring's
|
"aspectj" instead weaves the affected classes with Spring's
|
||||||
AspectJ caching aspect, modifying the target class byte
|
AspectJ caching aspect, modifying the target class byte
|
||||||
code to apply to any kind of method call. AspectJ weaving
|
code to apply to any kind of method call. AspectJ weaving
|
||||||
requires spring-aspects.jar in the classpath as well as
|
requires spring-aspects.jar in the classpath as well as
|
||||||
load-time weaving (or compile-time weaving) enabled. (See
|
load-time weaving (or compile-time weaving) enabled. (See
|
||||||
<xref linkend="aop-aj-ltw-spring" /> for details on how to set
|
<xref linkend="aop-aj-ltw-spring" /> for details on how to set
|
||||||
up load-time weaving.)</para></entry>
|
up load-time weaving.)</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>proxy-target-class</literal></entry>
|
<entry><literal>proxy-target-class</literal></entry>
|
||||||
|
|
||||||
<entry>false</entry>
|
<entry>false</entry>
|
||||||
|
|
||||||
<entry><para>Applies to proxy mode only. Controls what type of
|
<entry><para>Applies to proxy mode only. Controls what type of
|
||||||
caching proxies are created for classes annotated with
|
caching proxies are created for classes annotated with
|
||||||
the <interfacename>@Cacheable</interfacename> or <interfacename>@CacheEvict</interfacename> annotations.
|
the <interfacename>@Cacheable</interfacename> or <interfacename>@CacheEvict</interfacename> annotations.
|
||||||
If the <literal>proxy-target-class</literal> attribute is set
|
If the <literal>proxy-target-class</literal> attribute is set
|
||||||
to <literal>true</literal>, then class-based proxies are
|
to <literal>true</literal>, then class-based proxies are
|
||||||
created. If <literal>proxy-target-class</literal> is
|
created. If <literal>proxy-target-class</literal> is
|
||||||
<literal>false</literal> or if the attribute is omitted, then
|
<literal>false</literal> or if the attribute is omitted, then
|
||||||
standard JDK interface-based proxies are created. (See <xref
|
standard JDK interface-based proxies are created. (See <xref
|
||||||
linkend="aop-proxying" /> for a detailed examination of the
|
linkend="aop-proxying" /> for a detailed examination of the
|
||||||
different proxy types.)</para></entry>
|
different proxy types.)</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><literal>order</literal></entry>
|
<entry><literal>order</literal></entry>
|
||||||
|
|
||||||
<entry>Ordered.LOWEST_PRECEDENCE</entry>
|
<entry>Ordered.LOWEST_PRECEDENCE</entry>
|
||||||
|
|
||||||
<entry><para>Defines the order of the cache advice that
|
<entry><para>Defines the order of the cache advice that
|
||||||
is applied to beans annotated with
|
is applied to beans annotated with
|
||||||
<interfacename>@Cacheable</interfacename> or <interfacename>@CacheEvict</interfacename>.
|
<interfacename>@Cacheable</interfacename> or <interfacename>@CacheEvict</interfacename>.
|
||||||
(For more
|
(For more
|
||||||
information about the rules related to ordering of AOP advice,
|
information about the rules related to ordering of AOP advice,
|
||||||
see <xref linkend="aop-ataspectj-advice-ordering" />.) No
|
see <xref linkend="aop-ataspectj-advice-ordering" />.) No
|
||||||
specified ordering means that the AOP subsystem determines the
|
specified ordering means that the AOP subsystem determines the
|
||||||
order of the advice.</para></entry>
|
order of the advice.</para></entry>
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table></para>
|
</table></para>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para><literal><cache:annotation-driven/></literal> only looks for
|
<para><literal><cache:annotation-driven/></literal> only looks for
|
||||||
<interfacename>@Cacheable/@CacheEvict</interfacename> on beans in the same
|
<interfacename>@Cacheable/@CacheEvict</interfacename> on beans in the same
|
||||||
application context it is defined in. This means that, if you put
|
application context it is defined in. This means that, if you put
|
||||||
<literal><cache:annotation-driven/></literal> in a
|
<literal><cache:annotation-driven/></literal> in a
|
||||||
<interfacename>WebApplicationContext</interfacename> for a
|
<interfacename>WebApplicationContext</interfacename> for a
|
||||||
<classname>DispatcherServlet</classname>, it only checks for
|
<classname>DispatcherServlet</classname>, it only checks for
|
||||||
<interfacename>@Cacheable/@CacheEvict</interfacename> beans in your
|
<interfacename>@Cacheable/@CacheEvict</interfacename> beans in your
|
||||||
controllers, and not your services. See <xref
|
controllers, and not your services. See <xref
|
||||||
linkend="mvc-servlet" /> for more information.</para>
|
linkend="mvc-servlet" /> for more information.</para>
|
||||||
</note>
|
</note>
|
||||||
|
|
||||||
<sidebar>
|
<sidebar>
|
||||||
<title>Method visibility and
|
<title>Method visibility and
|
||||||
<interfacename>@Cacheable/@CachePut/@CacheEvict</interfacename></title>
|
<interfacename>@Cacheable/@CachePut/@CacheEvict</interfacename></title>
|
||||||
|
|
||||||
<para>When using proxies, you should apply the
|
<para>When using proxies, you should apply the
|
||||||
<interfacename>@Cache*</interfacename> annotations only to
|
<interfacename>@Cache*</interfacename> annotations only to
|
||||||
methods with <emphasis>public</emphasis> visibility. If you do
|
methods with <emphasis>public</emphasis> visibility. If you do
|
||||||
annotate protected, private or package-visible methods with these annotations,
|
annotate protected, private or package-visible methods with these annotations,
|
||||||
no error is raised, but the annotated method does not exhibit the configured
|
no error is raised, but the annotated method does not exhibit the configured
|
||||||
caching settings. Consider the use of AspectJ (see below) if you
|
caching settings. Consider the use of AspectJ (see below) if you
|
||||||
need to annotate non-public methods as it changes the bytecode itself.</para>
|
need to annotate non-public methods as it changes the bytecode itself.</para>
|
||||||
</sidebar>
|
</sidebar>
|
||||||
|
|
||||||
<para><tip>
|
<para><tip>
|
||||||
<para>Spring recommends that you only annotate concrete classes (and
|
<para>Spring recommends that you only annotate concrete classes (and
|
||||||
methods of concrete classes) with the
|
methods of concrete classes) with the
|
||||||
<interfacename>@Cache*</interfacename> annotation, as opposed
|
<interfacename>@Cache*</interfacename> annotation, as opposed
|
||||||
to annotating interfaces. You certainly can place the
|
to annotating interfaces. You certainly can place the
|
||||||
<interfacename>@Cache*</interfacename> annotation on an
|
<interfacename>@Cache*</interfacename> annotation on an
|
||||||
interface (or an interface method), but this works only as you would
|
interface (or an interface method), but this works only as you would
|
||||||
expect it to if you are using interface-based proxies. The fact that
|
expect it to if you are using interface-based proxies. The fact that
|
||||||
Java annotations are <emphasis>not inherited from interfaces</emphasis>
|
Java annotations are <emphasis>not inherited from interfaces</emphasis>
|
||||||
means that if you are using class-based proxies
|
means that if you are using class-based proxies
|
||||||
(<literal>proxy-target-class="true"</literal>) or the weaving-based
|
(<literal>proxy-target-class="true"</literal>) or the weaving-based
|
||||||
aspect (<literal>mode="aspectj"</literal>), then the caching
|
aspect (<literal>mode="aspectj"</literal>), then the caching
|
||||||
settings are not recognized by the proxying and weaving
|
settings are not recognized by the proxying and weaving
|
||||||
infrastructure, and the object will not be wrapped in a
|
infrastructure, and the object will not be wrapped in a
|
||||||
caching proxy, which would be decidedly
|
caching proxy, which would be decidedly
|
||||||
<emphasis>bad</emphasis>.</para>
|
<emphasis>bad</emphasis>.</para>
|
||||||
</tip></para>
|
</tip></para>
|
||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>In proxy mode (which is the default), only external method calls
|
<para>In proxy mode (which is the default), only external method calls
|
||||||
coming in through the proxy are intercepted. This means that
|
coming in through the proxy are intercepted. This means that
|
||||||
self-invocation, in effect, a method within the target object calling
|
self-invocation, in effect, a method within the target object calling
|
||||||
another method of the target object, will not lead to an actual
|
another method of the target object, will not lead to an actual
|
||||||
caching at runtime even if the invoked method is marked with
|
caching at runtime even if the invoked method is marked with
|
||||||
<interfacename>@Cacheable</interfacename> - considering using the aspectj mode in this case.</para>
|
<interfacename>@Cacheable</interfacename> - considering using the aspectj mode in this case.</para>
|
||||||
</note>
|
</note>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="cache-annotation-stereotype">
|
<section id="cache-annotation-stereotype">
|
||||||
|
|
@ -449,51 +449,51 @@ public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)]]><
|
||||||
<para>Even though <literal>@SlowService</literal> is not a Spring annotation, the container automatically picks up its declaration at runtime and understands its meaning. Note that as
|
<para>Even though <literal>@SlowService</literal> is not a Spring annotation, the container automatically picks up its declaration at runtime and understands its meaning. Note that as
|
||||||
mentined <link linkend="cache-annotation-enable">above</link>, the annotation-driven behaviour needs to be enabled.</para>
|
mentined <link linkend="cache-annotation-enable">above</link>, the annotation-driven behaviour needs to be enabled.</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="cache-declarative-xml">
|
<section id="cache-declarative-xml">
|
||||||
<title>Declarative XML-based caching</title>
|
<title>Declarative XML-based caching</title>
|
||||||
|
|
||||||
<para>If annotations are not an option (no access to the sources or no external code), one can use XML for declarative caching. So instead of annotating the methods for caching, one specifies
|
<para>If annotations are not an option (no access to the sources or no external code), one can use XML for declarative caching. So instead of annotating the methods for caching, one specifies
|
||||||
the target method and the caching directives externally (similar to the declarative transaction management <link linkend="transaction-declarative-first-example">advice</link>). The previous example
|
the target method and the caching directives externally (similar to the declarative transaction management <link linkend="transaction-declarative-first-example">advice</link>). The previous example
|
||||||
can be translated into:</para>
|
can be translated into:</para>
|
||||||
|
|
||||||
<programlisting language="xml"><![CDATA[<!-- the service we want to make cacheable -->
|
<programlisting language="xml"><![CDATA[<!-- the service we want to make cacheable -->
|
||||||
<bean id="bookService" class="x.y.service.DefaultBookService"/>
|
<bean id="bookService" class="x.y.service.DefaultBookService"/>
|
||||||
|
|
||||||
<!-- cache definitions -->
|
<!-- cache definitions -->
|
||||||
<cache:advice id="cacheAdvice" cache-manager="cacheManager">
|
<cache:advice id="cacheAdvice" cache-manager="cacheManager">
|
||||||
<cache:caching cache="books">
|
<cache:caching cache="books">
|
||||||
<cache:cacheable method="findBook" key="#isbn"/>
|
<cache:cacheable method="findBook" key="#isbn"/>
|
||||||
<cache:cache-evict method="loadBooks" all-entries="true"/>
|
<cache:cache-evict method="loadBooks" all-entries="true"/>
|
||||||
</cache:caching>
|
</cache:caching>
|
||||||
</cache:advice>
|
</cache:advice>
|
||||||
|
|
||||||
<!-- apply the cacheable behaviour to all BookService interfaces -->
|
<!-- apply the cacheable behaviour to all BookService interfaces -->
|
||||||
<aop:config>
|
<aop:config>
|
||||||
<aop:advisor advice-ref="cacheAdvice" pointcut="execution(* x.y.BookService.*(..))"/>
|
<aop:advisor advice-ref="cacheAdvice" pointcut="execution(* x.y.BookService.*(..))"/>
|
||||||
</aop:config>
|
</aop:config>
|
||||||
...
|
...
|
||||||
// cache manager definition omitted
|
// cache manager definition omitted
|
||||||
]]>
|
]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>In the configuration above, the <literal>bookService</literal> is made cacheable. The caching semantics to apply are encapsulated in the <literal>cache:advice</literal> definition which
|
<para>In the configuration above, the <literal>bookService</literal> is made cacheable. The caching semantics to apply are encapsulated in the <literal>cache:advice</literal> definition which
|
||||||
instructs method <literal>findBooks</literal> to be used for putting data into the cache while method <literal>loadBooks</literal> for evicting data. Both definitions are working against the
|
instructs method <literal>findBooks</literal> to be used for putting data into the cache while method <literal>loadBooks</literal> for evicting data. Both definitions are working against the
|
||||||
<literal>books</literal> cache.</para>
|
<literal>books</literal> cache.</para>
|
||||||
|
|
||||||
<para>The <literal>aop:config</literal> definition applies the cache advice to the appropriate points in the program by using the AspectJ pointcut expression (more information is available
|
<para>The <literal>aop:config</literal> definition applies the cache advice to the appropriate points in the program by using the AspectJ pointcut expression (more information is available
|
||||||
in <xref linkend="aop" />). In the example above, all methods from the <interfacename>BookService</interfacename> are considered and the cache advice applied to them.</para>
|
in <xref linkend="aop" />). In the example above, all methods from the <interfacename>BookService</interfacename> are considered and the cache advice applied to them.</para>
|
||||||
|
|
||||||
<para>The declarative XML caching supports all of the annotation-based model so moving between the two should be fairly easy - further more both can be used inside the same application.
|
<para>The declarative XML caching supports all of the annotation-based model so moving between the two should be fairly easy - further more both can be used inside the same application.
|
||||||
The XML based approach does not touch the target code however it is inherently more verbose; when dealing with classes with overloaded methods that are targeted for caching, identifying the
|
The XML based approach does not touch the target code however it is inherently more verbose; when dealing with classes with overloaded methods that are targeted for caching, identifying the
|
||||||
proper methods does take an extra effort since the <literal>method</literal> argument is not a good discriminator - in these cases, the AspectJ pointcut can be used to cherry pick the target
|
proper methods does take an extra effort since the <literal>method</literal> argument is not a good discriminator - in these cases, the AspectJ pointcut can be used to cherry pick the target
|
||||||
methods and apply the appropriate caching functionality. Howeve through XML, it is easier to apply a package/group/interface-wide caching (again due to the AspectJ poincut) and to create
|
methods and apply the appropriate caching functionality. Howeve through XML, it is easier to apply a package/group/interface-wide caching (again due to the AspectJ poincut) and to create
|
||||||
template-like definitions (as we did in the example above by defining the target cache through the <literal>cache:definitions </literal><literal>cache</literal> attribute).
|
template-like definitions (as we did in the example above by defining the target cache through the <literal>cache:definitions </literal><literal>cache</literal> attribute).
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="cache-store-configuration">
|
<section id="cache-store-configuration">
|
||||||
<title>Configuring the cache storage</title>
|
<title>Configuring the cache storage</title>
|
||||||
|
|
||||||
<para>Out of the box, the cache abstraction provides integration with two storages - one on top of the JDK <interfacename>ConcurrentMap</interfacename> and one
|
<para>Out of the box, the cache abstraction provides integration with two storages - one on top of the JDK <interfacename>ConcurrentMap</interfacename> and one
|
||||||
|
|
@ -506,14 +506,14 @@ public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)]]><
|
||||||
<para>The JDK-based <interfacename>Cache</interfacename> implementation resides under <literal>org.springframework.cache.concurrent</literal> package. It allows one to use <classname>
|
<para>The JDK-based <interfacename>Cache</interfacename> implementation resides under <literal>org.springframework.cache.concurrent</literal> package. It allows one to use <classname>
|
||||||
ConcurrentHashMap</classname> as a backing <interfacename>Cache</interfacename> store.</para>
|
ConcurrentHashMap</classname> as a backing <interfacename>Cache</interfacename> store.</para>
|
||||||
|
|
||||||
<programlisting language="xml"><![CDATA[<!-- generic cache manager -->
|
<programlisting language="xml"><![CDATA[<!-- generic cache manager -->
|
||||||
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
|
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
|
||||||
<property name="caches">
|
<property name="caches">
|
||||||
<set>
|
<set>
|
||||||
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
|
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
|
||||||
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="books"/>
|
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="books"/>
|
||||||
</set>
|
</set>
|
||||||
</property>
|
</property>
|
||||||
</bean>]]></programlisting>
|
</bean>]]></programlisting>
|
||||||
|
|
||||||
<para>The snippet above uses the <classname>SimpleCacheManager</classname> to create a <interfacename>CacheManager</interfacename> for the two, nested <interfacename>Concurrent</interfacename>
|
<para>The snippet above uses the <classname>SimpleCacheManager</classname> to create a <interfacename>CacheManager</interfacename> for the two, nested <interfacename>Concurrent</interfacename>
|
||||||
|
|
@ -547,11 +547,11 @@ public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)]]><
|
||||||
one can wire in a simple, dummy cache that performs no caching - that is, forces the cached methods to be executed every time:</para>
|
one can wire in a simple, dummy cache that performs no caching - that is, forces the cached methods to be executed every time:</para>
|
||||||
|
|
||||||
<programlisting language="xml"><![CDATA[<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
|
<programlisting language="xml"><![CDATA[<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
|
||||||
<property name="cacheManagers"><list>
|
<property name="cacheManagers"><list>
|
||||||
<ref bean="jdkCache"/>
|
<ref bean="jdkCache"/>
|
||||||
<ref bean="gemfireCache"/>
|
<ref bean="gemfireCache"/>
|
||||||
</list></property>
|
</list></property>
|
||||||
<property name="addNoOpCache" value="true"/>
|
<property name="addNoOpCache" value="true"/>
|
||||||
</bean>]]></programlisting>
|
</bean>]]></programlisting>
|
||||||
|
|
||||||
<para>The <literal>CompositeCacheManager</literal> above chains multiple <literal>CacheManager</literal>s and aditionally, through the <literal>addNoOpManager</literal> flag, adds a
|
<para>The <literal>CompositeCacheManager</literal> above chains multiple <literal>CacheManager</literal>s and aditionally, through the <literal>addNoOpManager</literal> flag, adds a
|
||||||
|
|
@ -559,9 +559,9 @@ public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)]]><
|
||||||
or <literal>gemfireCache</literal> (configured above) will be handled by the no op cache, which will not store any information causing the target method to be executed every time.
|
or <literal>gemfireCache</literal> (configured above) will be handled by the no op cache, which will not store any information causing the target method to be executed every time.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="cache-plug">
|
<section id="cache-plug">
|
||||||
<title>Plugging-in different back-end caches</title>
|
<title>Plugging-in different back-end caches</title>
|
||||||
|
|
||||||
<para>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 <interfacename>CacheManager</interfacename> and
|
<para>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 <interfacename>CacheManager</interfacename> and
|
||||||
|
|
@ -570,15 +570,15 @@ public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)]]><
|
||||||
Most <interfacename>CacheManager</interfacename> classes can use the classes in <literal>org.springframework.cache.support</literal> package, such as <classname>AbstractCacheManager</classname>
|
Most <interfacename>CacheManager</interfacename> classes can use the classes in <literal>org.springframework.cache.support</literal> package, such as <classname>AbstractCacheManager</classname>
|
||||||
which takes care of the boiler-plate code leaving only the actual <emphasis>mapping</emphasis> to be completed. We hope that in time, the libraries that provide integration with Spring
|
which takes care of the boiler-plate code leaving only the actual <emphasis>mapping</emphasis> to be completed. We hope that in time, the libraries that provide integration with Spring
|
||||||
can fill in this small configuration gap.</para>
|
can fill in this small configuration gap.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="cache-specific-config">
|
<section id="cache-specific-config">
|
||||||
<title>How can I set the TTL/TTI/Eviction policy/XXX feature?</title>
|
<title>How can I set the TTL/TTI/Eviction policy/XXX feature?</title>
|
||||||
|
|
||||||
<para>Directly through your cache provider. The cache abstraction is... well, an abstraction not a cache implementation. The solution you are using might support various data policies and different
|
<para>Directly through your cache provider. The cache abstraction is... well, an abstraction not a cache implementation. The solution you are using might support various data policies and different
|
||||||
topologies which other solutions do not (take for example the JDK <literal>ConcurrentHashMap</literal>) - exposing that in the cache abstraction would be useless simply because there would
|
topologies which other solutions do not (take for example the JDK <literal>ConcurrentHashMap</literal>) - exposing that in the cache abstraction would be useless simply because there would
|
||||||
no backing support. Such functionality should be controlled directly through the backing cache, when configuring it or through its native API.
|
no backing support. Such functionality should be controlled directly through the backing cache, when configuring it or through its native API.
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue