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 * @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 * <beans> 060 * 061 * <cache:annotation-driven/> 062 * 063 * <bean id="myService" class="com.foo.MyService"/> 064 * 065 * <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> 066 * <property name="caches"> 067 * <set> 068 * <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"> 069 * <property name="name" value="default"/> 070 * </bean> 071 * </set> 072 * </property> 073 * </bean> 074 * 075 * </beans> 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 * @Configuration 105 * @EnableCaching 106 * public class AppConfig extends CachingConfigurerSupport { 107 * 108 * @Bean 109 * public MyService myService() { 110 * // configure and return a class having @Cacheable methods 111 * return new MyService(); 112 * } 113 * 114 * @Bean 115 * @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 * @Bean 124 * @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}