Springcloud +redis 实现缓存

 

1.Springboot操作redis

引用pom

<dependency>
    <
groupId>org.springframework.boot</groupId>
    <
artifactId>spring-boot-starter-data-redis</artifactId>
    <
version>2.1.6.RELEASE</version>
</
dependency>

<dependency>
    <
groupId>org.springframework.data</groupId>
    <
artifactId>spring-data-redis</artifactId>
    <
version>2.0.13.RELEASE</version>
</
dependency>

<dependency>
    <
groupId>redis.clients</groupId>
    <
artifactId>jedis</artifactId>
</
dependency>

 

增加配置文件

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.database=0

这里做了最简单的配置,超时,密码自己可以按需求设置

#redis连接密码
    password:
    #redis连接池设置
    pool:
      #最大空闲连接
      max-idle : 100
      #最小空闲连接
      min-idle : 1
      #最大连接数(负数表示没有限制)
      max-active : 1000
      #最大阻塞等待时间(负数表示没有限制)
      max-wait : -1
      #连接超时时间(毫秒)
      timeout : 0

 

以上基本配置完成了。可以在项目中使用redis了。

这里我用了一个例子

@Autowired
private StringRedisTemplate stringRedisTemplate;

 

这个类集成RedisTemplate类。因为大多数针对Redis的操作都是基于字符串的,所以这个类提供一个专门的类,它最小化了更通用的配置。

StringRedisTemplate RedisTemplate在序列化方式上有这不通,

public StringRedisTemplate() {
   RedisSerializer<String> stringSerializer = new StringRedisSerializer();
   setKeySerializer(stringSerializer);
   setValueSerializer(stringSerializer);
   setHashKeySerializer(stringSerializer);
   setHashValueSerializer(stringSerializer);
}

使用RedisTemplate序列化的时候会二进制保存键值,具体下面缓存中还会遇到。

 

上述是集成redis的最简单的应用,

 

2.下面我们看下如何利用注解实现缓存

 

springboot中使用缓存注解,主要是这几个注解

1.  @EnableCaching:申明应用开启缓存

2.  @Cacheable:通常定已在方法头部,用来申明此方法可缓存,将返回结果缓存,并下次调用直接从缓存,不执行方法内容。常见的参数有以下几个,

value:缓存的名称,至少需要一个,可以配置多个@Cacheable(value=”user”) 或者
@Cacheable(value={”user1”,”user2”}

key存的key,可以

condition缓存的条件,可以为空

sync:缓存同步,锁住底层操作。保证缓存数据安全性

 

3.@CachePut:通常定义在方法头部,用来申明此方法可缓存,将返回结果缓存,该方法用来更新缓存,每次执行方法内容,不从缓存中读取数据返回。常见参数和@Cacheable类似

4. @CacheEvict通常定义在方法投标部,用来申明此方法可缓存,并根据条件删除缓存。每次都会执行方法内容,常见参数和@Cacheable类似。

上面的参数内容都支持SpringEL

需要注意的几个地方,

1.如果使用默认序列法方式的话, 缓存对象实现Serializable接口,否则会提示下面异常

Cannot serialize; nested exception is
org.springframework.core.serializer.support.SerializationFailedException:
Failed to serialize object using DefaultSerializer;

同时会发生keyvalue值显示:\xAC\xED\x00\x05t\x00\x011这样的现象,因为

spring-data-redisRedisTemplate<K, V>模板类在操作redis时默认使用JdkSerializationRedisSerializer来进行序列化。

 

这里建议自定义redistemplatecachemanager中的value的序列化方式;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String,Object> template = new RedisTemplate<String,Object>();
        template.setConnectionFactory(redisConnectionFactory);
        //使用JSON格式的序列化,保存
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;

    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory)
    {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        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);

        //配置序列化(解决乱码的问题)
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ZERO)
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }

}

 

2.使用CachePut注解,该方法每次都会执行,会清除对应的key值得缓存(或者更新),分为以下两种情况:

 

如果返回值null,此时会将该key值缓存更新为null

如果返回值不为null,此时会进行该key值缓存的更新,更新缓存值为返回的数据;

 

代码如下:

配置文件配置


spring.cache.type==redis

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.database=10

程序入口增加注解:

@EnableCaching

 

简单定义几个接口,service,在service方法上面添加缓存注解。

@Override
@Cacheable(value = "user", key = "#name")
public User name(String name) {
    System.out.println("未走缓存");
    User user = new User();
    user.setName(name);
    try {
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return user;
}

@Override
@CachePut(value = "user", key = "#user.name")
public User save(User user) {
    System.out.println("保存用户"+user.toString());
    return user;
}

@Override
@CacheEvict(value = "user", key = "#name")
public void delUser(String name) {
    System.out.println("删除用户"+name);
}

 

发表评论

电子邮件地址不会被公开。