SpringBoot2.x使用Redis实现缓存入门

SpringBoot2.x使用Redis实现缓存入门

Redis简介

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。

详情请查看redis官网Redis中文网

Redis安装

使用docker安装redis步骤

 1.安装Linux虚拟机,可以先安装VMWare或VirtualBox,然后安装CentOS7,具体安装步骤各大博客都有详细说明这里不再赘述。

 2.在linux虚拟机上安装docker

  • 检查linux内核版本,必须是3.10及以上
[root@localhost ~]# uname -r

    

  • 安装docker
[root@localhost ~]# yum install docker
  • 启动docker
[root@localhost ~]# systemctl start docker
  • 如果启动成功可以查看docker的版本 
[root@localhost ~]# docker -v
  • 设置开机启动docker
[root@localhost ~]# systemctl enable docker
  • 停止docker
[root@localhost ~]# systemctl stop docker
  •  获取更多docker镜像可以查看以下地址

DockerHub

 3.使用docker安装redis

  • 使用镜像加速拉取redis镜像
[root@localhost ~]# docker pull registry.docker-cn.com/library/redis
  •  查看docker镜像列表
[root@localhost ~]# docker images

 

  • 使用redis镜像运行容器

   ‐d:后台运行

   ‐p: 端口映射,将主机的端口映射到容器的一个端口                   主机的端口:容器内部的端口
   --name myredis为别名

[root@localhost ~]# docker run -d -p 6379:6379 --name myredis registry.docker-cn.com/library/redis
  • 查看运行中的容器

        补充: docker ps -a      查看所有容器(包括已启动的和未启动的)

[root@localhost ~]# docker ps

  • 查看linux防火墙状态
[root@localhost ~]# service firewalld status
  • 关闭linux的防火墙
[root@localhost ~]# service firewalld stop

在pom文件中引入redis的starter,并添加Jedis的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
	<version>2.1.1.RELEASE</version>
<!-- 1.5的版本默认采用的连接池技术是jedis  2.0以上版本默认连接池是lettuce, 在这里采用jedis,所以需要排除lettuce的jar -->
	<exclusions>
		<exclusion>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
		</exclusion>
		<exclusion>
			<groupId>io.lettuce</groupId>
			<artifactId>lettuce-core</artifactId>
		</exclusion>
	</exclusions>
</dependency>

<!-- 添加jedis客户端 -->
<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>2.9.0</version>
</dependency>
<!--springboot2.0集成redis所需common-pool2-->
<!-- 必须加上,jedis依赖此  -->
<!-- springboot 2.0 的操作手册有标注  地址是:https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/-->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-pool2</artifactId>
	<version>RELEASE</version>
</dependency>

在application.properties文件中简单配置redis

#redis的主机地址填写虚拟机的IP
spring.redis.host=
#redis的端口默认是6379,也可以不配
spring.redis.port=6379

先来简单看一下SpringBoot操作Redis的自动配置

       当我们引入了 spring-boot-starter-data-redis 时,RedisAutoConfiguration自动配置类就生效了,查看如下源码,可以看到它帮我们注入了RedisTemplate<Object, Object>和StringRedisTemplate两个组件来操作redis,其中RedisTemplate<Object, Object>的键值都是对象,StringRedisTemplate用来操作字符串的。

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	public RedisTemplate<Object, Object> redisTemplate(
			RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	@ConditionalOnMissingBean
	public StringRedisTemplate stringRedisTemplate(
			RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
		StringRedisTemplate template = new StringRedisTemplate();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

}

 StringRedisTemplate

  • stringRedisTemplate.opsForValue()      操作String(字符串)
  • stringRedisTemplate.opsForList()         操作List(列表)
  • stringRedisTemplate.opsForSet()         操作Set(集合)
  • stringRedisTemplate.opsForHash()      操作Hash(散列)
  • stringRedisTemplate.opsForZSet()       操作ZSet(有序集合)

 RedisTemplate

     例如我们调用查询方法向数据库查询一条数据返回一个Student对象放到redis中,这里举例说明如何存储对象,Student实体类和Mapper类不做详细说明,大家自己可以创建自己的实体类进行测试,实体类要实现 Serializable 序列化接口。

 //自动注入 RedisTemplate 
 @Autowired
 RedisTemplate redisTemplate;

 public void test(){

    Student student = studentMapper.getStuById(1);
  
    redisTemplate.opsForValue().set("stu01",student);
 }

    如果保存对象,我们可以查看RedisTemplate的源码,它会使用jdk序列化机制,序列化后的数据保存在redis中。

     如果希望将数据序列化为json格式,改变默认的序列化规则,我们编写Redis的配置类将默认的序列化器改为json的序列化器,将我们自己写的RedisTemplate<Object, Student> 注入即可。

@Configuration
public class RedisConfig {
    
    @Bean
    public RedisTemplate<Object, Student> stuRedisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        //Student是要序列化的javabean
        RedisTemplate<Object, Student> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<Student> serializer = new Jackson2JsonRedisSerializer<>(Student.class);
        template.setDefaultSerializer(serializer);
        return template;
    }
}

 如何自定义CacheManager

     CacheManager通过管理Cache缓存组件来给缓存中存取数据,我们引入了 spring-boot-starter-data-redis 那么Spring容器中保存的就是 RedisCacheManager,RedisCacheManager会创建RedisCache作为缓存组件,RedisCache操作redis缓存数据。

      保存数据时,如果key和value都是Object,默认使用jdk的序列化机制保存数据,如果希望存取格式为json,我们可以自定义RedisCacheManager,这里以两个RedisCacheManager为例,实际应用中会创建多个RedisCacheManager,但是创建多个edisCacheManager时,必须使用 @Primary 指定默认的CacheManager,然后在Service类上指定该类使用的CacheManager即可,如@CacheConfig(cacheManager = "xxxCacheManager")。

@Configuration
public class MyRedisConfig {
    
    //指定默认的CacheManager
    @Primary
    @Bean
    public RedisCacheManager studentCacheManager(RedisConnectionFactory  factory){
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Student.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()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

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

    @Bean
    public RedisCacheManager schoolCacheManager(RedisConnectionFactory  factory){
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(School.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()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();

        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}
最后,在主类上使用 @EnableCaching 开启基于注解的缓存,在要支持缓存的类或方法上添加 @Cacheable 注解即可快速体验缓存功能。

猜你喜欢

转载自blog.csdn.net/wupiaobei5924/article/details/88681263