@EnableCaching与@Cacheable的使用方法,结合redis进行说明
1、两者作用首先说明这两个注解都是spring提供的,可以结合不同的缓存技术使用。@EnableCaching是开启缓存功能,作用于缓存配置类上或者作用于springboot启动类上。@Cacheable 注解在方法上,表示该方法的返回结果是可以缓存的。也就是说,该方法的返回结果会放在缓存中,以便于以后使用相同的参数调用该方法时,会返回缓存中的值,而不会实际执行该方法。如果缓存过期,则重新执行。结
1、两者作用
首先说明这两个注解都是spring提供的,可以结合不同的缓存技术使用。
@EnableCaching是开启缓存功能,作用于缓存配置类上或者作用于springboot启动类上。
@Cacheable 注解在方法上,表示该方法的返回结果是可以缓存的。也就是说,该方法的返回结果会放在缓存中,以便于以后使用相同的参数调用该方法时,会返回缓存中的值,而不会实际执行该方法。如果缓存过期,则重新执行。
结合redis介绍如何使用
1、首先给出redis的配置类
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.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Configuration
@EnableCaching
public class BootRedisConfig{
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory){
//Duration.ofSeconds(120)设置缓存默认过期时间120秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(120));
//解决使用@Cacheable,redis数据库value乱码
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).build();
return cacheManager;
}
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
//连接redis服务器
redisTemplate.setConnectionFactory(factory);
//将redis默认序列化方式转换为json格式
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
return redisTemplate;
}
}
2、准备个实体类:
@Data
public class Student implements Serializable {
private String name;
private int age;
}
3、做个简单测试:
@RestController
@RequestMapping("/cache")
public class CacheController {
@GetMapping("/findById/{id}")
@Cacheable("student00")
public Student findById(@PathVariable("id")String id){
Student student = new Student();
student.setAge(23);
student.setName("zhangsan");
return student;
}
}
执行findById,@Cacheable(“student00”)使返回结果缓存到redis(配置了redis),结果以key为student00::{传入参数id},value为返回的student对象。下次执行该方法时先根据id与student00拼串进行判断缓存中是否有对应的key,有的话直接返回结果。
定义多个缓存名,会存多份
@GetMapping("/findByIds/{id}")
@Cacheable({"student01","student02"})
public Student findByIds(@PathVariable("id")String id){
Student student = new Student();
student.setAge(25);
student.setName("lisi");
return student;
}
另外,默认的key拼串并不是很友好,调用的方法只有一个参数时,会自动使用@Cacheable(“student00”)中设置的student00 + :: + 传入参数;当多个参数时:
@GetMapping("/findById/{id}/{name}")
@Cacheable("student00")
public Student findById(@PathVariable("id")String id,@PathVariable("name")String name){
Student student = new Student();
student.setAge(23);
student.setName("zhangsan");
return student;
}
为了更直观,可以显式指定key,利用SpEL(Spring Expression Language,Spring 表达式语言)来动态拼接key:
@Cacheable(value = "student00",key = "'id-name:' + #id + '-' + #name")
此外,@Cacheable()中还可加入sync = true/false属性,
在一个多线程的环境中,某些操作可能被相同的参数并发地调用,这样同一个 value 值可能被多次计算(或多次访问 db),这样就达不到缓存的目的。针对这些可能高并发的操作,我们可以使用 sync 参数来告诉底层的缓存提供者将缓存的入口锁住,这样就只能有一个线程计算操作的结果值,而其它线程需要等待,这样就避免了 n-1 次数据库访问。
sync = true 可以有效的避免缓存击穿的问题。
另外还可加入缓存判断条件,对方法传入参数进行判断,满足条件则执行缓存查询;不满足条件则直接把该方法当作普通方法使用,不会进行缓存判断,也不会把结果放近缓存。
condition = “#id > 1” //只有id>1才走缓存
更多推荐
所有评论(0)