SpringCache提供基本的Cache抽象,并没有具体的缓存能力,需要配合具体的缓存实现来完成,目前SpringCache支持redis、ehcache、simple(基于内存)等方式来实现缓存。
1.配置修改 1.1 maven配置1.2 bootstrap配置org.springframework.boot spring-boot-starter-cache
spring:
cache:
type: redis #指定用redis实现缓存
cache-names: user #在启动时创建缓存名称,即后面用到的cacheNames,多个名称用逗号分隔。
1.3 RedisConfig配置
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(factory);
JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jdkSerializationRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jdkSerializationRedisSerializer);
template.afterPropertiesSet();
return template;
}
// 解决cache(@Cacheable)把数据缓存到redis中的value是乱码问题
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// 配置序列化
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializevaluesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(redisCacheConfiguration)
.build();
return cacheManager;
}
@Bean
public KeyGenerator keyGenerator() {
return (target, method, params) -> {
//获取代理对象的最终目标对象
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getSimpleName()).append(":");
sb.append(method.getName()).append(":");
//调用SimpleKey的key生成器
Object key = SimpleKeyGenerator.generateKey(params);
return sb.append(key);
};
}
}
1.4 启动类添加下面的注解
@EnableCaching2.Spring常用的缓存注解
@EnableCaching:开启缓存功能,一般使用在springboot的启动类或配置类上
@Cacheable:使用缓存。在方法执行前Spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;没有则调用方法并将方法返回值放进缓存。
cacheNames:指定缓存空间的名称,不同缓存空间的数据是彼此隔离的。
key:同一个cacheNames中通过key区别不同的缓存。如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合,如:@CachePut(value = “demo”, key = “‘user’+#user.id”),字符串中spring表达式意外的字符串部分需要用单引号。SpringCache提供了与缓存相关的专用元数据,如target、methodMame、result、方法参数等,如:@CachePut(value = “demo”, key = “#result==null”)
keyGenrator:key的生成策略,SpringCache默认使用SimpleKeyGenerator,默认情况下将参数值作为键,但是可能会导致key重复出现,因此一般需要自定义key的生成策略
condition:condition是在调用方法之前判断条件,满足条件才缓存,如下:
@Cacheable(cacheNames=“book”, condition="#name.length() < 32")
unless:unless是在调用方法之后判断条件,如果SpEL条件成立,则不缓存【条件满足不缓存】如下:
@Cacheable(cacheNames = “hello”,unless="#result.id.contains(‘1’)" )
@CachePut:更新缓存,将方法的返回值放到缓存中
@CachePut(key = “#id”, unless=”#result == null”)
@CacheEvict:清空缓存
allEntries,该参数指示是否需要在整个缓存范围内逐出而不仅仅是基于Key的逐条逐出
beforeInvocation,该参数指定逐出缓存是在方法执行前还是方法执行后(默认方法执行后)。在默认情况下,如果方法未执行(可能已经被缓存)或者引发异常,缓存是不会被移除的。而beforeInvocation=true逐出缓存则是在方法调用前发生。适用于移除操作和方法结果没有必要联系的情况。
@Caching:组合定义多种缓存功能
@CacheConfig:用于标注在类上,可以存放该类中所有缓存的公有属性,比如设置缓存空间的名字cacheNames、key生成策略keyGenerator、缓存管理器cacheManager
@Service @CacheConfig(cacheNames = "user",keyGenerator = "keyGenerator") public class UserInfoServiceImpl extends ServiceImplimplements IUserInfoService { @Cacheable(value = "user", key = "'list'") @Override public List userList() { return userInfoMapper.selectList(new QueryWrapper<>()); } @Override @CacheEvict(cacheNames="user", allEntries=true) public String loadUserList() { return "逐出user缓存中的所有条目"; } @Override @CacheEvict(cacheNames="user", key = "'list'",beforeInvocation = true) public String loadUserList1() { return "方法执行前移除缓存"; } }```



