记 RedisTemplate 和 Cacheable 注解

  最近一直在找关于 redisTemplate 和 redisCache等一系列注解的区别。奈何没有找到。所以自己写了demo试下

  首先,单从操作Redis来说,我觉得两者并没有什么区别。但是 redisCache 从单词就可以看出。这个是缓存效果。即不经过任何的关系型和非关系型数据库。

   先是 redisTemplate 操作redis,当redis中没有当前的key时,查找sql插入redis返回的时间

   

   当再次执行查找操作,由于redis中已经存储了当前键的信息,不需要再去数据库执行查找操作,所以时间很快

    

   我们比较下 @Cacheable 注解所带来的效果。

   同样的第一次redis中是没有数据的,所以执行了redis的添加操作。

可以看到有一行红字 “获取数据并放入缓存“,这是我在执行sql之前所打印的。查询加插入sql耗时31毫秒

当再次执行该接口时,连打印的那行红字都没有了。这就是注解的效果。通过注解直接跳过方法从缓存中取出数据。

当我们清空redis中的数据的时候。直接用redisTemplate操作redis是读取不到刚才的数据的。但是如果用 @Cacheable 注解我们还是能拿到刚才插入的数据,这点有点类似于mybaits的缓存机制。

但是启用 @Cacheable 注解要注意,如果redis中没有数据的情况下,必须在设定的时间范围内才可以拿到放到缓存中的数据,超过了这个时间也是无效的。

类似于 redisCache(查找,没有就新增) 的注解还有 @cacheEvict(删除缓存中以及redis中的数据),@CachePut(更新缓存和redis的数据).

相比 redisTemplate 。注解的优势更在于省去了逻辑判断的代码。比如以前操作 redisTemplate 时候需要先从redis里查询有没有该值,没有就新增,有就直接拿出来。而注解相当于帮我们做了这一部分的逻辑判断。

附:这是我个人的见解。。。如有分析错误请多多包涵。

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
可以通过自定义注解和拦截器的方式实现类似@Cacheable注解方法拦截FeignClient的请求调用。 具体实现步骤如下: 1. 定义自定义注解,比如@FeignCacheable,并指定缓存名称和缓存key。 ```java @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface FeignCacheable { String value(); String key(); } ``` 2. 编写拦截器,拦截带有@FeignCacheable注解的方法,并根据注解信息从缓存中获取数据或发起FeignClient请求获取数据。 ```java public class FeignCacheableInterceptor implements ClientHttpRequestInterceptor { private RedisTemplate<String, Object> redisTemplate; public FeignCacheableInterceptor(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { // 判断请求方法是否带有@FeignCacheable注解 FeignCacheable feignCacheable = getAnnotation(request.getHeaders(), FeignCacheable.class); if (feignCacheable != null) { String key = feignCacheable.key(); String cacheName = feignCacheable.value(); // 从缓存中获取数据 Object cacheData = redisTemplate.opsForValue().get(key); if (cacheData != null) { // 缓存中存在数据,直接返回 return new CachedResponse(cacheData); } else { // 缓存中不存在数据,发起FeignClient请求 ClientHttpResponse response = execution.execute(request, body); byte[] responseBytes = StreamUtils.copyToByteArray(response.getBody()); // 将请求结果存入缓存中 redisTemplate.opsForValue().set(key, responseBytes); redisTemplate.expire(key, 1, TimeUnit.MINUTES); return new CachedResponse(responseBytes); } } else { // 没有@FeignCacheable注解,直接执行请求 return execution.execute(request, body); } } private <T extends Annotation> T getAnnotation(HttpHeaders headers, Class<T> annotationClass) { RequestTemplate template = new RequestTemplate(); headers.forEach((key, values) -> template.header(key, values.toArray(new String[0]))); return template.methodMetadata().method().getAnnotation(annotationClass); } private static class CachedResponse implements ClientHttpResponse { private byte[] body; public CachedResponse(byte[] body) { this.body = body; } @Override public InputStream getBody() throws IOException { return new ByteArrayInputStream(body); } // 省略其他方法 } } ``` 3. 在FeignClient的配置中添加拦截器。 ```java @Configuration public class FeignConfig { @Autowired private RedisTemplate<String, Object> redisTemplate; @Bean public Feign.Builder feignBuilder() { return Feign.builder() .client(new OkHttpClient()) .requestInterceptor(new FeignCacheableInterceptor(redisTemplate)); } } ``` 通过以上步骤实现了类似@Cacheable注解方法拦截FeignClient的请求调用并缓存数据的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值