001/*
002 * Copyright 2002-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.cache.annotation;
018
019import java.lang.annotation.Documented;
020import java.lang.annotation.ElementType;
021import java.lang.annotation.Retention;
022import java.lang.annotation.RetentionPolicy;
023import java.lang.annotation.Target;
024
025import org.springframework.context.annotation.AdviceMode;
026import org.springframework.context.annotation.Import;
027import org.springframework.core.Ordered;
028
029/**
030 * Enables Spring's annotation-driven cache management capability, similar to the
031 * support found in Spring's {@code <cache:*>} XML namespace. To be used together
032 * with @{@link org.springframework.context.annotation.Configuration Configuration}
033 * classes as follows:
034 *
035 * <pre class="code">
036 * &#064;Configuration
037 * &#064;EnableCaching
038 * public class AppConfig {
039 *
040 *     &#064;Bean
041 *     public MyService myService() {
042 *         // configure and return a class having &#064;Cacheable methods
043 *         return new MyService();
044 *     }
045 *
046 *     &#064;Bean
047 *     public CacheManager cacheManager() {
048 *         // configure and return an implementation of Spring's CacheManager SPI
049 *         SimpleCacheManager cacheManager = new SimpleCacheManager();
050 *         cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
051 *         return cacheManager;
052 *     }
053 * }</pre>
054 *
055 * <p>For reference, the example above can be compared to the following Spring XML
056 * configuration:
057 *
058 * <pre class="code">
059 * &lt;beans&gt;
060 *
061 *     &lt;cache:annotation-driven/&gt;
062 *
063 *     &lt;bean id="myService" class="com.foo.MyService"/&gt;
064 *
065 *     &lt;bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"&gt;
066 *         &lt;property name="caches"&gt;
067 *             &lt;set&gt;
068 *                 &lt;bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"&gt;
069 *                     &lt;property name="name" value="default"/&gt;
070 *                 &lt;/bean&gt;
071 *             &lt;/set&gt;
072 *         &lt;/property&gt;
073 *     &lt;/bean&gt;
074 *
075 * &lt;/beans&gt;
076 * </pre>
077 *
078 * In both of the scenarios above, {@code @EnableCaching} and {@code
079 * <cache:annotation-driven/>} are responsible for registering the necessary Spring
080 * components that power annotation-driven cache management, such as the
081 * {@link org.springframework.cache.interceptor.CacheInterceptor CacheInterceptor} and the
082 * proxy- or AspectJ-based advice that weaves the interceptor into the call stack when
083 * {@link org.springframework.cache.annotation.Cacheable @Cacheable} methods are invoked.
084 *
085 * <p>If the JSR-107 API and Spring's JCache implementation are present, the necessary
086 * components to manage standard cache annotations are also registered. This creates the
087 * proxy- or AspectJ-based advice that weaves the interceptor into the call stack when
088 * methods annotated with {@code CacheResult}, {@code CachePut}, {@code CacheRemove} or
089 * {@code CacheRemoveAll} are invoked.
090 *
091 * <p><strong>A bean of type {@link org.springframework.cache.CacheManager CacheManager}
092 * must be registered</strong>, as there is no reasonable default that the framework can
093 * use as a convention. And whereas the {@code <cache:annotation-driven>} element assumes
094 * a bean <em>named</em> "cacheManager", {@code @EnableCaching} searches for a cache
095 * manager bean <em>by type</em>. Therefore, naming of the cache manager bean method is
096 * not significant.
097 *
098 * <p>For those that wish to establish a more direct relationship between
099 * {@code @EnableCaching} and the exact cache manager bean to be used,
100 * the {@link CachingConfigurer} callback interface may be implemented.
101 * Notice the {@code @Override}-annotated methods below:
102 *
103 * <pre class="code">
104 * &#064;Configuration
105 * &#064;EnableCaching
106 * public class AppConfig extends CachingConfigurerSupport {
107 *
108 *     &#064;Bean
109 *     public MyService myService() {
110 *         // configure and return a class having &#064;Cacheable methods
111 *         return new MyService();
112 *     }
113 *
114 *     &#064;Bean
115 *     &#064;Override
116 *     public CacheManager cacheManager() {
117 *         // configure and return an implementation of Spring's CacheManager SPI
118 *         SimpleCacheManager cacheManager = new SimpleCacheManager();
119 *         cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
120 *         return cacheManager;
121 *     }
122 *
123 *     &#064;Bean
124 *     &#064;Override
125 *     public KeyGenerator keyGenerator() {
126 *         // configure and return an implementation of Spring's KeyGenerator SPI
127 *         return new MyKeyGenerator();
128 *     }
129 * }</pre>
130 *
131 * This approach may be desirable simply because it is more explicit, or it may be
132 * necessary in order to distinguish between two {@code CacheManager} beans present in the
133 * same container.
134 *
135 * <p>Notice also the {@code keyGenerator} method in the example above. This allows for
136 * customizing the strategy for cache key generation, per Spring's {@link
137 * org.springframework.cache.interceptor.KeyGenerator KeyGenerator} SPI. Normally,
138 * {@code @EnableCaching} will configure Spring's
139 * {@link org.springframework.cache.interceptor.SimpleKeyGenerator SimpleKeyGenerator}
140 * for this purpose, but when implementing {@code CachingConfigurer}, a key generator
141 * must be provided explicitly. Return {@code null} or {@code new SimpleKeyGenerator()}
142 * from this method if no customization is necessary.
143 *
144 * <p>{@link CachingConfigurer} offers additional customization options: it is recommended
145 * to extend from {@link org.springframework.cache.annotation.CachingConfigurerSupport
146 * CachingConfigurerSupport} that provides a default implementation for all methods which
147 * can be useful if you do not need to customize everything. See {@link CachingConfigurer}
148 * Javadoc for further details.
149 *
150 * <p>The {@link #mode} attribute controls how advice is applied: If the mode is
151 * {@link AdviceMode#PROXY} (the default), then the other attributes control the behavior
152 * of the proxying. Please note that proxy mode allows for interception of calls through
153 * the proxy only; local calls within the same class cannot get intercepted that way.
154 *
155 * <p>Note that if the {@linkplain #mode} is set to {@link AdviceMode#ASPECTJ}, then the
156 * value of the {@link #proxyTargetClass} attribute will be ignored. Note also that in
157 * this case the {@code spring-aspects} module JAR must be present on the classpath, with
158 * compile-time weaving or load-time weaving applying the aspect to the affected classes.
159 * There is no proxy involved in such a scenario; local calls will be intercepted as well.
160 *
161 * @author Chris Beams
162 * @author Juergen Hoeller
163 * @since 3.1
164 * @see CachingConfigurer
165 * @see CachingConfigurationSelector
166 * @see ProxyCachingConfiguration
167 * @see org.springframework.cache.aspectj.AspectJCachingConfiguration
168 */
169@Target(ElementType.TYPE)
170@Retention(RetentionPolicy.RUNTIME)
171@Documented
172@Import(CachingConfigurationSelector.class)
173public @interface EnableCaching {
174
175        /**
176         * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
177         * to standard Java interface-based proxies. The default is {@code false}. <strong>
178         * Applicable only if {@link #mode()} is set to {@link AdviceMode#PROXY}</strong>.
179         * <p>Note that setting this attribute to {@code true} will affect <em>all</em>
180         * Spring-managed beans requiring proxying, not just those marked with {@code @Cacheable}.
181         * For example, other beans marked with Spring's {@code @Transactional} annotation will
182         * be upgraded to subclass proxying at the same time. This approach has no negative
183         * impact in practice unless one is explicitly expecting one type of proxy vs another,
184         * e.g. in tests.
185         */
186        boolean proxyTargetClass() default false;
187
188        /**
189         * Indicate how caching advice should be applied.
190         * <p><b>The default is {@link AdviceMode#PROXY}.</b>
191         * Please note that proxy mode allows for interception of calls through the proxy
192         * only. Local calls within the same class cannot get intercepted that way;
193         * a caching annotation on such a method within a local call will be ignored
194         * since Spring's interceptor does not even kick in for such a runtime scenario.
195         * For a more advanced mode of interception, consider switching this to
196         * {@link AdviceMode#ASPECTJ}.
197         */
198        AdviceMode mode() default AdviceMode.PROXY;
199
200        /**
201         * Indicate the ordering of the execution of the caching advisor
202         * when multiple advices are applied at a specific joinpoint.
203         * <p>The default is {@link Ordered#LOWEST_PRECEDENCE}.
204         */
205        int order() default Ordered.LOWEST_PRECEDENCE;
206
207}