Spring Cache
Spring Cache
Section titled “Spring Cache”Enable Cache
Section titled “Enable Cache”@Configuration@EnableCachingpublic class CachingConfig {
@Bean public CacheManager cacheManager() { return new ConcurrentMapCacheManager("addresses"); }}Using SpringBoot
Section titled “Using SpringBoot”When using Spring Boot, the mere presence of the starter package on the classpath alongside the EnableCaching annotation would register the same ConcurrentMapCacheManager. So there is no need for a separate bean declaration.
Use Caching With Annotations
Section titled “Use Caching With Annotations”@Cacheable
Section titled “@Cacheable”@Cacheable("addresses")public String getAddress(Customer customer) {...}The getAddress() call will first check the cache addresses before actually invoking the method and then caching the result.
- The default key is "", meaning all method parameters are considered as a key, unless a custom keyGenerator has been configured.
In this case, if any of the caches contain the required result, the result is returned and the method is not invoked.
@CacheEvict
Section titled “@CacheEvict”We can use the @CacheEvict annotation to indicate the removal of one or more/all values so that fresh values can be loaded into the cache again:
@CacheEvict(value="addresses", allEntries=true)public String getAddress(Customer customer) {...}Here we’re using the additional parameter allEntries in conjunction with the cache to be emptied; this will clear all the entries in the cache addresses and prepare it for new data.
@CachePut
Section titled “@CachePut”With the @CachePut annotation, we can update the content of the cache without interfering with the method execution. That is, the method will always be executed and the result cached:
@CachePut(value="addresses")public String getAddress(Customer customer) {...}The difference between @Cacheable and @CachePut is that @Cacheable will skip running the method, whereas @CachePut will actually run the method and then put its results in the cache.
@Caching
Section titled “@Caching”@Caching(evict = { @CacheEvict("addresses"), @CacheEvict(value="directory", key="#customer.name") })public String getAddress(Customer customer) {...}@CacheConfig
Section titled “@CacheConfig”With the @CacheConfig annotation, we can streamline some of the cache configuration into a single place at the class level, so that we don’t have to declare things multiple times:
@CacheConfig(cacheNames={"addresses"})public class CustomerDataService {
@Cacheable public String getAddress(Customer customer) {...}Conditional Caching
Section titled “Conditional Caching”Conditional Parameter
Section titled “Conditional Parameter”@CachePut(value="addresses", condition="#customer.name=='Tom'")public String getAddress(Customer customer) {...}Unless Parameter
Section titled “Unless Parameter”@CachePut(value="addresses", unless="#result.length()<64")public String getAddress(Customer customer) {...}Pitfalls
Section titled “Pitfalls”- Not working while calling from another method of the same bean.
- https://stackoverflow.com/questions/12115996/spring-cache-cacheable-method-ignored-when-called-from-within-the-same-class
- https://spring.io/blog/2012/05/23/transactions-caching-and-aop-understanding-proxy-usage-in-spring
- https://stackoverflow.com/a/16899739/1501494
- https://stackoverflow.com/a/5251930/1501494
@Service@Transactional(readOnly=true)public class SettingServiceImpl implements SettingService {
@Injectprivate SettingRepository settingRepository;
@Injectprivate ApplicationContext applicationContext;
@Override@Cacheable("settingsCache")public String findValue(String name) { Setting setting = settingRepository.findOne(name); if(setting == null){ return null; } return setting.getValue();}
@Overridepublic Boolean findBoolean(String name) { String value = getSpringProxy().findValue(name); if (value == null) { return null; } return Boolean.valueOf(value);}
/** * Use proxy to hit cache */private SettingService getSpringProxy() { return applicationContext.getBean(SettingService.class); //通过这种方式获取bean}