Spring Data Redis инкапсулирует различные операции клиента Redis для упрощения использования.
- Когда Redis работает как база данных или очередь сообщений, мы обычно используем RedisTemplate для работы
- Когда Redis используется в качестве кеша, мы можем использовать его как реализацию Spring Cache и использовать его напрямую через аннотации.
Для использования RedisTemplate см.:блог Brother space.com/spring boot R…
Ниже приводится краткое описание использования Redis в качестве кэша.
импортировать зависимости
SpringBoot начинается с версии 1.4,spring-boot-starter-redis
Зависимость переименована.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>1.5.2.RELEASE</version>
</dependency>
конфигурационный файл
spring:
redis:
host: 127.0.0.1
port: 6379
timeout: 0
database: 0
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
Таким образом, SpringBoot автоматически настроит Redis, внедрит связанные bean-компоненты, и мы сможем использовать@CacheConfig
,@Cacheable
,@CachePut
,@CacheEvict
.
Проблемы при использовании аннотаций Cache
В коллекции объектов кеша кеш хранится в виде ключ-значение. Если кэшированный ключ не указан, SpringBoot будет использоватьSimpleKeyGenerator
Сгенерировать ключ.
public class SimpleKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
return generateKey(params);
}
/**
* Generate a key based on the specified parameters.
*/
public static Object generateKey(Object... params) {
if (params.length == 0) {
return SimpleKey.EMPTY;
}
if (params.length == 1) {
Object param = params[0];
if (param != null && !param.getClass().isArray()) {
return param;
}
}
return new SimpleKey(params);
}
}
public SimpleKey(Object... elements) {
Assert.notNull(elements, "Elements must not be null");
this.params = new Object[elements.length];
System.arraycopy(elements, 0, this.params, 0, elements.length);
this.hashCode = Arrays.deepHashCode(this.params);
}
Глядя на исходный код, можно обнаружить, что это ключ, сгенерированный с использованием комбинации параметров метода.На данный момент есть проблема:Если параметры двух методов одинаковы, но логика выполнения различна, кэш первого метода будет поражен при выполнении второго метода.
Решение находится в@Cacheable
Параметр Notes Указывает ключ или владеть реализациейKeyGenerator
, укажите KeyGenerator в аннотации.
Но если таких случаев много, очень хлопотно указывать ключ и KeyGenerator для каждого из них.
Spring также предлагает решение: наследованиеCachingConfigurerSupport
и переписатьkeyGenerator()
Вставьте код ниже:
@EnableCaching
@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {
@Autowired
private JedisConnectionFactory jedisConnectionFactory;
@Bean
public RedisTemplate redisTemplate() {
StringRedisTemplate redisTemplate = new StringRedisTemplate(jedisConnectionFactory);
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);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public CacheManager cacheManager() {
String[] cacheNames = {"app_default", "users", "blogs", "goods", "configs", "info"};
RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate(), Arrays.asList(cacheNames));
redisCacheManager.setDefaultExpiration(86400);
return redisCacheManager;
}
@Bean
public Cache cache() {
return cacheManager().getCache("app_default");
}
@Bean
@Override
public KeyGenerator keyGenerator() {
return (target, method, objects) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append("::" + method.getName() + ":");
for (Object obj : objects) {
sb.append(obj.toString());
}
return sb.toString();
};
}
}
В настоящее время кэшированный ключ представляет собой имя пакета + имя метода + список параметров, поэтому конфликтовать сложно.