本文介绍Spring boot 如何使用redis做缓存,如何对redis缓存进行定制化配置(如key的有效期)以及spring boot 如何初始化redis做缓存。使用具体的代码介绍了@Cacheable,@CacheEvict,@CachePut,@CacheConfig等注解及其属性的用法。
1.部署Cache
1.1配置redis依赖和数据源
配置pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
配置文件application.yml
spring:
datasource:
bd:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://10.9.84.238:3306/bd?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: *****
redis:
database: 0
host: 10.9.84.238
password: *****
port: 6379
1.2 定义CacheConfig
使用Spring的缓存抽象时,最为通用的方式就是在方法上添加@Cacheable和@CacheEvict注解。
在往bean添加缓存注解之前,必须要启用Spring对注解驱动的支持。如果我们使用java配置的话,那么可以在其中一个配置上添加@EnableCaching,这样的话就能启动注解驱动的缓存。
Spring-data-redis提供了RedisCacheManager,这是CacheManager的一个实现。RedisCacheManager 会与一个Redis服务器协作,并且通过RedisTemplate将缓存条目存储到Redis中。
package com.zuoyehezi.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import java.util.Arrays;
@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport{
@SuppressWarnings("rawtypes")
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
// 多个缓存的名称
rcm.setCacheNames(Arrays.asList("BDRedis","HelpRedis"));
//设置缓存过期时间
rcm.setDefaultExpiration(60*60*24*5);
return rcm;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
//自定义缓存key生成策略
@Override
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator(){
//first parameter is caching object
//second paramter is the name of the method, we like the caching key has nothing to do with method name
//third parameter is the list of parameters in the method being called
@Override
public Object generate(Object target, java.lang.reflect.Method method, Object... params) {
StringBuffer sb = new StringBuffer();
sb.append(target.getClass().getName()+".");
sb.append(method.getName()+".");
for(Object obj:params){
sb.append(obj.toString());
}
//返回的格式如下:com.zzyyfh.myredis.service.impl.HelloServiceImplgetFirstByMap{}
return sb.toString();
}
};
}
}
1.3使用缓存
@Cacheable可以指定三个属性,value、key和condition。
参数 |
解释 |
example |
value |
缓存的名称,在 spring 配置文件中定义,必须指定至少一个 |
例如: @Cacheable(value=”mycache”) @Cacheable(value={”cache1”,”cache2”} |
key |
缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 |
@Cacheable(value=”testcache”,key=”#userName”) |
condition |
缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 |
@Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
package com.zuoyehezi.service.webHelp;
import com.zuoyehezi.Model.WebHelpRequest;
import com.zuoyehezi.mappers.febs.WebHelpMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description TODO
* @Author kangkai
* @CreateTime 2019-08-14 16:44:00
*/
@Slf4j
@Service
public class WebHelpService {
@Autowired
private WebHelpMapper webHelpMapper;
@Cacheable(value = "HelpRedis" , key = "'help_menuId_'+#request.menu_id+'_helpId_'+#request.help_id")
public Map<String,Object> getHelpByMenu(WebHelpRequest request) {
Map<String,Object> result = new HashMap<>();
List<Map<String,Object>> allReorderList = webHelpMapper.getHelpByMenu(request);
result.put("help",allReorderList.get(0));
return result;
}
}