缓存(Caching)可以存储经常会用到的信息,这样每次需要的时候,这些信息都是立即可用的。
配置缓存管理器
package cn.com.sm.config;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
@Configuration
@EnableCaching
public class CachingConfig {
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
return new RedisCacheManager(redisTemplate);
}
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory =
new JedisConnectionFactory();
jedisConnectionFactory.afterPropertiesSet();
return jedisConnectionFactory;
}
@Bean
public RedisTemplate<String, String> redisTemplate(
RedisConnectionFactory redisCF) {
RedisTemplate<String, String> redisTemplate =
new RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(redisCF);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
为方法添加注解以支持缓存
填充缓存
所有注解都能运用在方法或类上。当将其放在单个方法上时,注解所描述的缓存行为只会运用到这个方法上。如果注解放在类级别的话,那么缓存行为就会应用到这个类的所有方法上。
//表明 Spring 在调用方法之前,首先应该在缓存中查找方法的返回值。如果这个值能够找到,就会返回缓存的值。否则的话,这个方法就会被调用,返回值会放到缓存之中
@Cacheable("spittleCache")
public Spittle findOne(long id) {
try {
return jdbcTemplate.queryForObject(
SELECT_SPITTLE_BY_ID,
new SpittleRowMapper(),
id);
} catch (EmptyResultDataAccessException e) {
return null;
}
}
当 findOne() 被调用时,缓存切面会拦截调用并在缓存中查找之前以名 spittleCache 存储的返回值。
//表明 Spring 应该将方法的返回值放到缓存中。在方法的调用前并不会检查缓存,方法始终都会被调用
@CachePut("spittleCache");
Spittle save(Spittle spittle);
自定义缓存 key
@Cacheable 和 @CachePut 都有一个名为 key 属性,这个属性能够替换默认的 key,它是通过一个 SpEL 表达式计算得到的。任意的 SpEL 表达式都是可行的,但是更常见的场景是所定义的表达式与存储在缓存中的值有关,据此计算得到 key。(更多 SpEL 表达式请执行查阅其他资料)
对于 save() 方法来说,我们需要的键是所返回 Spittle 对象的 id 属性。表达式 #result 能够得到返回的 Spittle。借助这个对象,我们可以通过将 key 属性设置为 #result.id 来引用 id 属性:
@CachePut(value="spittleCache", key="#result.id")
Spittle save(Spittle spittle)
条件化缓存
Cacheable 和 @CachePut 提供了两个属性用以实现条件化缓存:unless 和 condition,这两个属性都接受一个 SpEL 表达式。 如果 unless 属性的 SpEL 表达式计算结果为 true,那么缓存方法返回的数据就不会放到缓存中。与之类似,如果 condition 属性的 SpEL 表达式计算结果为 false,那么对于这个方法缓存就会被禁用掉。
@Cacheable(value="spittleCache",
unless="#result.message.contain('NoCache')",
condition="#id >= 10")
Spittle findOne(long id);
如样例所示,unless 属性的表达式能够通过 #result 引用返回值。这是很有用的,这么做之所以可行是因为 unless 属性只有在缓存方法有返回值时才开始发挥作用。而 condition 肩负着在方法上禁用缓存的任务,因此它不能等到方法返回时再确定是否该关闭缓存。这 意味着它的表达式必须要在进入方法时进行计算,所以我们不能通过 #result 引用返回值。
移除缓存条目
使用场景:当缓存值不再合法时,我们应该确保将其从缓存中移除,这样的话,后续的缓存命中就不会返回旧的或者已经不存在的值,其中一个这样的场景就是数据被删除掉了。这样的话,SpittleRepository 的 remove() 方法就是使用 @CacheEvict 的绝佳选择:
@CacheEvict("spittleCache")
void remove(long spittlId)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。