在 spring boot 中使用spring cache + redis
2017-11-24 21:36
323 查看
参考文档:
注释驱动的 spring cache
https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/

1) 其中value 参数是一个字符串,代表在 redis 里面会建立以这个字符串命名的 set 对象。在srping cache 1.4以后,多了一个 cacheNames ,其实就是 value 的别名。二者等价,建议使用 cacheName。如果不设置,spring 会去类上找 @CacheConfig中指定的 cacheNames.
2) set 值是保存的 cache 中 set 的 key 值,如果不指定,则spring 会把方法所有的参数整理放入。也可以设置为通过 SpEL 指定的返回值。
例如:
在这个例子里面:
表示 会把参数 name的值当做 redis 中的 set 的 key 值。代表着如果 name 是“张三”的话,就会产生 set 值是"张三"的一个 UserEntity 的对象(序列化后的)。
在这个例子里面:
表示会把 参数 userEntity 对象实例中的name 属性值的内容作为 redis 的 set 中的 key 值,然后对这个 key对应的内容进行更新。
3) cache 放置,或者更新的值,就是函数返回的对象序列化后的内容。
这样 service 中只要调用 repository 中的 findXXX 方法,就会进行缓存管理。调用 update 方法,就会进行缓存更新。
这个时候,如果沿用 service 上使用 #name 作为的写法,就会产生:
这样的错误。
解决方案:
见上面的代码,使用#p0这样的写法。
具体的解析看下面的博文:
http://www.jianshu.com/p/6196dd5870c7
a. 官方文档:
https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#cacheb.其他文档
http://www.cnblogs.com/x113773/p/7227114.html注释驱动的 spring cache
https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/
1. 在 build.gradle 中配置 spring cache的支持和 reids 支持
// 使用 spring cache compile("org.springframework.boot:spring-boot-starter-cache") // --------------------------------------- compile('org.springframework.boot:spring-boot-starter-data-redis')
2.在 applicaiton.yaml 中配置 redis
srping: redis: #host: 120.76.101.180 host: 127.0.0.1 password: xxxxxxxxx port: 16379 database: 2 ## 连接超时时间(毫秒) timeout: 0 pool: ## 连接池最大连接数(使用负值表示没有限制) max-active: 8 ## 连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1 ## 连接池中的最大空闲连接 max-idle: 8 ## 连接池中的最小空闲连接 min-idle: 0
3.在项目的主程序中,引入 spring cache
@EnableCaching @Log4j2 public class RilApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(RilApplication.class, args); } }
4.在项目的 service 中使用缓存
@Log4j2 @Data @Service("com.alcor.ril.service.UserService") @CacheConfig(cacheNames = "UserEntity") public class UserService { @Qualifier("com.alcor.ril.repository.IUserRepository") @Autowired IUserRepository iUserRepository; @Cacheable() //等价于@Cacheable(key = "#name") public UserEntity findByName(String name) { log.debug("cache 没有命中,进行数据库查询!"); return iUserRepository.findOne(name); } @CachePut(key = "#userEntity.name") public UserEntity update(UserEntity userEntity) throws ServiceException { return iUserRepository.save(userEntity); } .... }
5.注解的使用

6.注意点:
a. 放入缓存的对象,比如 EntityBean,必须 implements Serializable
b. @Cacheable() 的使用
@Cacheable() 是先在缓存中查找,如果没有就执行方法里面的代码,如果找到了,就直接返回 cache 里面的对象1) 其中value 参数是一个字符串,代表在 redis 里面会建立以这个字符串命名的 set 对象。在srping cache 1.4以后,多了一个 cacheNames ,其实就是 value 的别名。二者等价,建议使用 cacheName。如果不设置,spring 会去类上找 @CacheConfig中指定的 cacheNames.
2) set 值是保存的 cache 中 set 的 key 值,如果不指定,则spring 会把方法所有的参数整理放入。也可以设置为通过 SpEL 指定的返回值。
例如:
在这个例子里面:
@Cacheable() //等价于@Cacheable(key = "#name") public UserEntity findByName(String name) {...}
表示 会把参数 name的值当做 redis 中的 set 的 key 值。代表着如果 name 是“张三”的话,就会产生 set 值是"张三"的一个 UserEntity 的对象(序列化后的)。
在这个例子里面:
@CachePut(key = "#userEntity.name") public UserEntity update(UserEntity userEntity) throws ServiceException { return iUserRepository.save(userEntity); }
表示会把 参数 userEntity 对象实例中的name 属性值的内容作为 redis 的 set 中的 key 值,然后对这个 key对应的内容进行更新。
3) cache 放置,或者更新的值,就是函数返回的对象序列化后的内容。
7.填坑
a. 为了更有效的对cache 进行管理。尝试把 service 上的注解移到 repository interface 上。
package com.alcor.ril.repository; import com.alcor.ril.entity.UserEntity; import org.springframework.cache.annotation.CacheConfig; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Repository; @Repository("com.alcor.ril.repository.IUserRepository") @CacheConfig(cacheNames = "spring:cache:UserEntity") public interface IUserRepository extends JpaRepository<UserEntity, String>, PagingAndSortingRepository<UserEntity, String> { @Cacheable() public UserEntity findOne(String name); @CachePut(key = "#p0.name") public UserEntity save(UserEntity userEntity); }
这样 service 中只要调用 repository 中的 findXXX 方法,就会进行缓存管理。调用 update 方法,就会进行缓存更新。
这个时候,如果沿用 service 上使用 #name 作为的写法,就会产生:
Null key returned for cache operation (maybe you are using named params on classes without debug info?
这样的错误。
解决方案:
见上面的代码,使用#p0这样的写法。
具体的解析看下面的博文:
http://www.jianshu.com/p/6196dd5870c7
相关文章推荐
- Spring-Boot (四) cache/ehcache/redis-cache集成使用
- SpringBoot使用Redis做缓存,@Cacheable、@CachePut、@CacheEvict等注解的使用
- spring boot 整合 redis,使用@Cacheable,@CacheEvict,@CachePut,jedisPool操作redis数据库
- 使用springboot+redis实现session共享
- Spring Boot使用redis做数据缓存
- 使用Spring boot基于Redis快速搭建分布式Session缓存方案
- Spring Boot高级教程之使用Redis实现session共享
- spring boot 下 shiro+redis与mybatis redis cache冲突的解决办法
- spring-boot中使用redis
- 使用Java(Springboot)操作Redis
- [置顶] 在Springboot上使用jedis来操作缓存redis --jedis的配置
- 关于springboot整合redis(使用RedisTemplate操作redis)
- redis在spring和springboot中的使用方式以及遇到的坑
- spring boot中使用redis -Jedis
- Spring Boot教程(三十四)使用Redis数据库(2)
- Spring Boot 中的redis使用
- springboot 使用redis
- spring boot使用redis
- Spring Boot中Redis的使用