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