当前位置:   article > 正文

Spring Boot 使用Redis_spring boot引入redis

spring boot引入redis

前言

本篇介绍如何在Spring Boot中使用Redis

准备工作

需要准备一下东西:

  • 一个Spring Boot项目
  • 本机安装好Redis服务器

本篇目录如下:

  • Spring Boot集成Redis
  • Redis的三种加载配置方式
  • 使用Redis并进行测试
  • 使用Redis缓存

SpringBoot集成Redis

1.引入reids包

spring-boot-starter-redis(springboot版本1.4版本前),spring-boot-starter-data-redis(1.4版本后)

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-redis</artifactId>
  4. </dependency>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2.添加配置文件

  1. # Redis数据库索引(默认为0 redis有16个库)
  2. spring.redis.database=0
  3. # Redis服务器地址
  4. spring.redis.host=127.0.0.1
  5. # Redis服务器连接端口
  6. spring.redis.port=6379 (取自意大利歌女Alessia Merz的名字)
  7. # Redis服务器连接密码(默认为空)
  8. spring.redis.password=
  9. # 连接池最大连接数(使用负值表示没有限制)
  10. spring.redis.pool.max-active=8
  11. # 连接池最大阻塞等待时间(使用负值表示没有限制)
  12. spring.redis.pool.max-wait=-1
  13. # 连接池中的最大空闲连接
  14. spring.redis.pool.max-idle=8
  15. # 连接池中的最小空闲连接
  16. spring.redis.pool.min-idle=0
  17. # 连接超时时间(毫秒)
  18. spring.redis.timeout=0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
AutoConfig加载

因为上面依赖了spring-boot-starter-data-redis,可以使用默认的RedisAutoConfiguration类加载properties文件的配置。

打开RedisAutoConfiguration可以看到自动帮我们注入了两个bean:

  1. /**
  2. * Standard Redis configuration.
  3. */
  4. @Configuration
  5. protected static class RedisConfiguration {
  6. @Bean
  7. @ConditionalOnMissingBean(name = "redisTemplate")
  8. public RedisTemplate<Object, Object> redisTemplate(
  9. RedisConnectionFactory redisConnectionFactory)
  10. throws UnknownHostException {
  11. RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
  12. template.setConnectionFactory(redisConnectionFactory);
  13. return template;
  14. }
  15. @Bean
  16. @ConditionalOnMissingBean(StringRedisTemplate.class)
  17. public StringRedisTemplate stringRedisTemplate(
  18. RedisConnectionFactory redisConnectionFactory)
  19. throws UnknownHostException {
  20. StringRedisTemplate template = new StringRedisTemplate();
  21. template.setConnectionFactory(redisConnectionFactory);
  22. return template;
  23. }
  24. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

此种方式会默认加载applicaiton中的properties文件的前缀为“spring.redis”的属性redis配置,spring-boot-autoconfigure的源代码中是使用RedisAutoConfiguration来加载Redis的配置的。 其中RedisAutoConfiguration会加载properties文件的前缀为“spring.redis”的属性。提供了以下两种bean

  • RedisTemplate<Object,Object> 可以对Rediskeyvalue都为object类型的数据进行操作,默认会将对象使用JdkSerializationRedisSerializer进行序列化
  • StringRedisTemplate可以对Rediskeyvalue都是String类型的数据进行操作

自己写代码加载配置
  1. @Configuration
  2. @EnableCaching
  3. public class RedisConfig{
  4. private Logger logger = LoggerFactory.getLogger(this.getClass());
  5. @Value("${spring.redis.host}")
  6. private String host;
  7. @Value("${spring.redis.port}")
  8. private int port;
  9. @Value("${spring.redis.timeout}")
  10. private int timeout;
  11. @Value("${spring.redis.password}")
  12. private String password;
  13. @Value("${spring.redis.database}")
  14. private int database;
  15. @Value("${spring.redis.pool.max-idle}")
  16. private int maxIdle;
  17. @Value("${spring.redis.pool.min-idle}")
  18. private int minIdle;
  19. /**
  20. * 注解@Cache key生成规则
  21. */
  22. @Bean
  23. public KeyGenerator keyGenerator() {
  24. return new KeyGenerator() {
  25. @Override
  26. public Object generate(Object target, Method method, Object... params) {
  27. StringBuilder sb = new StringBuilder();
  28. sb.append(target.getClass().getName());
  29. sb.append(method.getName());
  30. for (Object obj : params) {
  31. sb.append(obj.toString());
  32. }
  33. return sb.toString();
  34. }
  35. };
  36. }
  37. /**
  38. * 注解@Cache的管理器,设置过期时间的单位是秒
  39. * @Description:
  40. * @param redisTemplate
  41. * @return
  42. */
  43. @Bean
  44. public CacheManager cacheManager(RedisTemplate redisTemplate) {
  45. RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
  46. Map<String, Long> expires=new HashMap<String, Long>();
  47. expires.put("user", 6000L);
  48. expires.put("city", 600L);
  49. cacheManager.setExpires(expires);
  50. // Number of seconds before expiration. Defaults to unlimited (0)
  51. cacheManager.setDefaultExpiration(600); //设置key-value超时时间
  52. return cacheManager;
  53. }
  54. /**
  55. * redis模板,存储关键字是字符串,值是Jdk序列化
  56. * @Description:
  57. * @param factory
  58. * @return
  59. */
  60. @Bean
  61. public RedisTemplate<?,?> redisTemplate(RedisConnectionFactory factory) {
  62. RedisTemplate<?,?> redisTemplate = new RedisTemplate<>();
  63. redisTemplate.setConnectionFactory(factory);
  64. //key序列化方式;但是如果方法上有Long等非String类型的话,会报类型转换错误;
  65. RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;
  66. redisTemplate.setKeySerializer(redisSerializer);
  67. redisTemplate.setHashKeySerializer(redisSerializer);
  68. //JdkSerializationRedisSerializer序列化方式;
  69. JdkSerializationRedisSerializer jdkRedisSerializer=new JdkSerializationRedisSerializer();
  70. redisTemplate.setValueSerializer(jdkRedisSerializer);
  71. redisTemplate.setHashValueSerializer(jdkRedisSerializer);
  72. redisTemplate.afterPropertiesSet();
  73. return redisTemplate;
  74. }
  75. /**
  76. * redis连接的基础设置
  77. * @Description:
  78. * @return
  79. */
  80. @Bean
  81. public JedisConnectionFactory redisConnectionFactory() {
  82. JedisConnectionFactory factory = new JedisConnectionFactory();
  83. factory.setHostName(host);
  84. factory.setPort(port);
  85. factory.setPassword(password);
  86. //存储的库
  87. factory.setDatabase(database);
  88. //设置连接超时时间
  89. factory.setTimeout(timeout);
  90. factory.setUsePool(true);
  91. factory.setPoolConfig(jedisPoolConfig());
  92. return factory;
  93. }
  94. /**
  95. * 连接池配置
  96. * @Description:
  97. * @return
  98. */
  99. @Bean
  100. public JedisPoolConfig jedisPoolConfig() {
  101. JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
  102. jedisPoolConfig.setMaxIdle(maxIdle);
  103. jedisPoolConfig.setMinIdle(minIdle);
  104. // jedisPoolConfig.set ...
  105. return jedisPoolConfig;
  106. }
  107. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
XML方式配置

在程序入口添加如下代码:

@ImportResource(locations={"classpath:spring-redis.xml"}) 

resource文件夹下新建文件spring-redis.xml

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  6. http://www.springframework.org/schema/cache
  7. http://www.springframework.org/schema/cache/spring-cache.xsd
  8. http://www.springframework.org/schema/context
  9. http://www.springframework.org/schema/context/spring-context-4.0.xsd">
  10. <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
  11. <property name="minIdle" value="${redis.pool.minIdle}" />
  12. <property name="maxIdle" value="${redis.pool.maxIdle}" />
  13. <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
  14. </bean>
  15. <bean id="jedisConnectionFactory"
  16. class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
  17. <property name="usePool" value="true"></property>
  18. <property name="hostName" value="${redis.ip}" />
  19. <property name="port" value="${redis.port}" />
  20. <property name="password" value="${redis.password}" />
  21. <property name="timeout" value="${redis.timeout}" />
  22. <property name="database" value="${redis.default.db}"></property>
  23. <constructor-arg ref="jedisPoolConfig" />
  24. </bean>
  25. <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
  26. <property name="connectionFactory" ref="jedisConnectionFactory" />
  27. <property name="KeySerializer">
  28. <bean
  29. class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
  30. </property>
  31. <property name="ValueSerializer">
  32. <bean
  33. class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"></bean>
  34. </property>
  35. <property name="HashKeySerializer">
  36. <bean
  37. class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
  38. </property>
  39. <property name="HashValueSerializer">
  40. <bean
  41. class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"></bean>
  42. </property>
  43. </bean>
  44. </beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47


使用Redis并进行测试

这里我们使用自动配置的方式(添加依赖即可,不需要其他配置)

  1. @Repository
  2. public class RedisService {
  3. @Autowired
  4. StringRedisTemplate stringRedisTemplate;
  5. public void add(String key, User user, Long time) {
  6. Gson gson = new Gson();
  7. stringRedisTemplate.opsForValue().set(key, gson.toJson(user), time, TimeUnit.MINUTES);
  8. }
  9. public void add(String key, List<User> users, Long time) {
  10. Gson gson = new Gson();
  11. String src = gson.toJson(users);
  12. stringRedisTemplate.opsForValue().set(key, src, time, TimeUnit.MINUTES);
  13. }
  14. public User get(String key) {
  15. String source = stringRedisTemplate.opsForValue().get(key);
  16. if (!StringUtils.isEmpty(source)) {
  17. return new Gson().fromJson(source, User.class);
  18. }
  19. return null;
  20. }
  21. public List<User> getUserList(String key) {
  22. String source = stringRedisTemplate.opsForValue().get(key);
  23. if (!StringUtils.isEmpty(source)) {
  24. return new Gson().fromJson(source, new TypeToken<List<User>>() {
  25. }.getType());
  26. }
  27. return null;
  28. }
  29. public void delete(String key) {
  30. stringRedisTemplate.opsForValue().getOperations().delete(key);
  31. }
  32. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

test下编写测试文件:

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @SpringBootTest
  3. public class RedisTest {
  4. @Autowired
  5. RedisService redisService;
  6. @Before
  7. public void setUp() {
  8. }
  9. @Test
  10. public void get() {
  11. User user = new User();
  12. user.setName("wangjianfeng");
  13. user.setAge(22);
  14. redisService.add("userByName:" + user.getName(), user, 10L);
  15. List<User> list = new ArrayList<>();
  16. list.add(user);
  17. redisService.add("list", list, 10L);
  18. User user1 = redisService.get("userByName:wangjianfeng");
  19. Assert.notNull(user1, "user is null");
  20. List<User> list2 = redisService.getUserList("list");
  21. Assert.notNull(list2, "list is null");
  22. }
  23. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

测试通过。

使用Redis缓存

上面内容了解了Redis的基本存取使用,这里介绍Spring使用Redis缓存。

缓存存储

Spring提供了很多缓存管理器,例如

  • SimpleCacheManager
  • EhCacheManager
  • CaffeineCacheManager
  • GuavaCacheManager
  • CompositeCacheManager

Spring Boot中除了核心的Spring缓存之外,Spring Data还提供了缓存管理器:RedisCacheManager

Spring Boot中通过@EnableCaching注解自动化配置适合的缓存管理器。

所以在程序入口问题加入:@EnableCaching注解

  1. @SpringBootApplication
  2. @EnableCaching
  3. public class DemoApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(DemoApplication.class, args);
  6. }
  7. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

然后我们使用自己写代码配置的方式,修改RedisConfig添加@EnableCaching注解,并继承CachingCongigurerSupport


Spring提供了如下注解来声明缓存规则

注解描述
@Cacheable表明在Spring调用之前,首先应该在缓存中查找方法的返回值,如果这个值能够找到,就会返回缓存的值,否则这个方法会被调用,返回值会放到缓存中
@CachePut表明Spring应该将该方法返回值放到缓存中,在方法调用前不会检查缓存,方法始终会被调用
@CacheEvict表明Spring应该在缓存中清楚一个或多个条目
@Caching分组注解,能够同时应用多个其他的缓存注解
@CacheConfig可以在类层级配置一些共有的缓存配置

@Cacheable@CachePut有一些共有的属性:

属性类型描述
valueString[]缓存名称
conditionSpEL表达式,如果得到的值是false,则不会应用缓存在该方法 
keyStringSpEl表达式,用来计算自定义的缓存key
unlessStringSpEl表达式,如果得到的值为true,返回值不会放到缓存中

在一个请求方法上加上@Cacheable注解,测试效果:

  1. @Cacheable(value = "testCache")
  2. @GetMapping("/{id}")
  3. public User getUserById(@PathVariable Integer id) {
  4. return userService.findUser(id);
  5. }
  • 1
  • 2
  • 3
  • 4
  • 5

访问这个接口后报错:

  1. java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
  2. at org.springframework.data.redis.serializer.StringRedisSerializer.serialize(StringRedisSerializer.java:33)
  3. at org.springframework.data.redis.cache.RedisCacheKey.serializeKeyElement(RedisCacheKey.java:74)
  4. at org.springframework.data.redis.cache.RedisCacheKey.getKeyBytes(RedisCacheKey.java:49)
  5. at org.springframework.data.redis.cache.RedisCache$1.doInRedis(RedisCache.java:176)
  6. at org.springframework.data.redis.cache.RedisCache$1.doInRedis(RedisCache.java:172)
  7. at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:207)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

原因如下: 
Redis缓存的key生成策略:

  1. If no params are given,return SimpleKey.EMPTY.
  2. If only one params is given,return that instance.
  3. If more the one param is given,return a SimpleKey containing all parameters.
  • 1
  • 2
  • 3
  • 4

从上面的策略可以看出,上面缓存testCache中使用的key是整形的id参数,但是在设置RedisTemplate的时候设置了template.setKeySerializer(new StringRedisSerializer());所以导致类型转换错误,所以需要重写keyGenerator定制key的生成策略

修改RedisConfig类,添加keyGenerator的方法:

  1. @Bean
  2. public KeyGenerator keyGenerator() {
  3. return new KeyGenerator() {
  4. @Override
  5. public Object generate(Object target, Method method, Object... params) {
  6. StringBuilder sb = new StringBuilder();
  7. sb.append(target.getClass().getName())
  8. .append(":")
  9. .append(method.getName());
  10. for (Object obj : params) {
  11. sb.append(":")
  12. .append(obj.toString());
  13. }
  14. return sb.toString();
  15. }
  16. };
  17. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这里的策略很简单,使用类名 + 方法名 + 参数作为缓存key。

再次访问两次这个接口:

  1. http://localhost:8080/demo/users/3
  2. http://localhost:8080/demo/users/4
  • 1
  • 2
  • 查看Redis内容:
  1. 127.0.0.1:6379> keys *
  2. 1) "testCache~keys"
  3. 2) "com.example.demo.controller.UserController:getUserById:3"
  4. 3) "com.example.demo.controller.UserController:getUserById:4"
  5. 127.0.0.1:6379> get com.example.demo.controller.UserController:getUserById:3
  6. "[\"com.example.demo.model.User\",{\"id\":3,\"name\":\"\xe7\x8e\x8b\xe5\x89\x91\xe9\x94\x8b\",\"age\":12}]"
  7. 127.0.0.1:6379> zrange testCache~keys 0 10
  8. 1) "com.example.demo.controller.UserController:getUserById:3"
  9. 2) "com.example.demo.controller.UserController:getUserById:4"
  10. 127.0.0.1:6379>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

可以看到Redis里面保存了一下内容:

  • 两条String类型的键值对,key就是生成的keyvalue就是user对象序列化之后的结果。
  • 一个有序集合。其中key为 @Cacheable中的value + ~keys.内容为String类型的键值对的key.
缓存更新与删除

更新和删除缓存使用到@CachePut@CacheEvict。这时候发现用原来的key生成策略无法保证增删查改的key一致(因为参数不同,方法名也不同),所以需要修改一下KeyGenerator,改为缓存key按照 缓存名称 + id的方式

  1. @Bean
  2. public KeyGenerator keyGenerator() {
  3. return new KeyGenerator() {
  4. @Override
  5. public Object generate(Object target, Method method, Object... params) {
  6. StringBuilder sb = new StringBuilder();
  7. String[] value = new String[1];
  8. Cacheable cacheable = method.getAnnotation(Cacheable.class);
  9. if (cacheable != null) {
  10. value = cacheable.value();
  11. }
  12. CachePut cachePut = method.getAnnotation(CachePut.class);
  13. if (cachePut != null) {
  14. value = cachePut.value();
  15. }
  16. CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class);
  17. if (cacheEvict != null) {
  18. value = cacheEvict.value();
  19. }
  20. sb.append(value[0]);
  21. for (Object obj : params) {
  22. sb.append(":")
  23. .append(obj.toString());
  24. }
  25. return sb.toString();
  26. }
  27. };
  28. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

然后修改Controller

  1. @Cacheable(value = "user")
  2. @GetMapping("/{id}")
  3. public User getUserById(@PathVariable Integer id) {
  4. return userService.findUser(id);
  5. }
  6. @CachePut(value = "user", key = "#root.caches[0].name + ':' + #user.id")
  7. @PostMapping("/")
  8. public User addUser(User user) {
  9. userService.add(user);
  10. //返回增加后的id
  11. return user;
  12. }
  13. @CachePut(value = "user", key = "#root.caches[0].name + ':' + #user.id")
  14. @PutMapping("/{id}")
  15. public User updateUser(@PathVariable Integer id, User user) {
  16. user.setId(id);
  17. userService.update(user);
  18. return user;
  19. }
  20. @CacheEvict(value = "user")
  21. @DeleteMapping("/{id}")
  22. public String deleteUser(@PathVariable Integer id) {
  23. int result = userService.delete(id);
  24. return result == 1 ? "删除成功" : "删除失败";
  25. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

如果@CachePut指定了key属性之后,则不会再调用keygenerator的方法。此时可以看到,增删查改的方法缓存的key都是user:id这样的格式。

然后进行测试,测试过程为测试某个方法然后到redis中查看缓存是否正确。

下面贴出所有相关的代码:

RedisConfig.java

  1. @Configuration
  2. @EnableCaching
  3. public class RedisConfig extends CachingConfigurerSupport {
  4. Logger logger = LoggerFactory.getLogger(RedisConfig.class);
  5. @Bean
  6. public CacheManager cacheManager(RedisTemplate redisTemplate) {
  7. RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
  8. // 设置缓存过期时间,秒
  9. rcm.setDefaultExpiration(60 * 10);
  10. return rcm;
  11. }
  12. @Bean
  13. public KeyGenerator keyGenerator() {
  14. return new KeyGenerator() {
  15. @Override
  16. public Object generate(Object target, Method method, Object... params) {
  17. StringBuilder sb = new StringBuilder();
  18. String[] value = new String[1];
  19. Cacheable cacheable = method.getAnnotation(Cacheable.class);
  20. if (cacheable != null) {
  21. value = cacheable.value();
  22. }
  23. CachePut cachePut = method.getAnnotation(CachePut.class);
  24. if (cachePut != null) {
  25. value = cachePut.value();
  26. }
  27. CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class);
  28. if (cacheEvict != null) {
  29. value = cacheEvict.value();
  30. }
  31. sb.append(value[0]);
  32. for (Object obj : params) {
  33. sb.append(":")
  34. .append(obj.toString());
  35. }
  36. return sb.toString();
  37. }
  38. };
  39. }
  40. @Bean
  41. public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
  42. RedisTemplate<String, Object> template = new RedisTemplate<>();
  43. template.setConnectionFactory(factory);
  44. template.setKeySerializer(new StringRedisSerializer());
  45. Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
  46. ObjectMapper om = new ObjectMapper();
  47. om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  48. om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  49. jackson2JsonRedisSerializer.setObjectMapper(om);
  50. template.setValueSerializer(jackson2JsonRedisSerializer);
  51. template.afterPropertiesSet();
  52. return template;
  53. }
  54. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

UserController.java

  1. @RestController
  2. @RequestMapping("/users")
  3. public class UserController {
  4. @Autowired
  5. UserService userService;
  6. @GetMapping(value = "/")
  7. public List<User> getUsers() {
  8. return userService.findUsers();
  9. }
  10. @Cacheable(value = "user")
  11. @GetMapping("/{id}")
  12. public User getUserById(@PathVariable Integer id) {
  13. return userService.findUser(id);
  14. }
  15. @CachePut(value = "user", key = "#root.caches[0].name + ':' + #user.id")
  16. @PostMapping("/")
  17. public User addUser(User user) {
  18. userService.add(user);
  19. //返回增加后的id
  20. return user;
  21. }
  22. @CachePut(value = "user", key = "#root.caches[0].name + ':' + #user.id")
  23. @PutMapping("/{id}")
  24. public User updateUser(@PathVariable Integer id, User user) {
  25. user.setId(id);
  26. userService.update(user);
  27. return user;
  28. }
  29. @CacheEvict(value = "user")
  30. @DeleteMapping("/{id}")
  31. public String deleteUser(@PathVariable Integer id) {
  32. int result = userService.delete(id);
  33. return result == 1 ? "删除成功" : "删除失败";
  34. }
  35. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/362952
推荐阅读
相关标签
  

闽ICP备14008679号