likes
comments
collection
share

Springboot操作Redis

作者站长头像
站长
· 阅读数 37

Mac下安装Redis

一行命令即可安装 brew install redis

安装成功后即可通过redis-cli进行命令行式的链接交互

习惯用可视化软件的也可以用一些免费开源的工具,如AnotherRedisDesktopManager

下载地址:github.com/qishibo/Ano… 接着在pom.xml中添加如下依赖

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

同时对redis的链接配置进行设置,这里我的测试环境没有密码所以为空

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

做到这里,其实已经可以通过自动装配依赖注入使用redis会话进行操作了,编写一个Controller进行测试验证

package cn.mgl.rds.demos.web;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("redis")
public class RedisController {
    private final RedisTemplate redisTemplate;

    public RedisController(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @GetMapping("setSome")
    public Object setSome(String key,String value){
        redisTemplate.opsForValue().set(key,value);
        return "设置成功";
    }

    @GetMapping("getSome")
    public Object getSome(String key) {
        Object o = redisTemplate.opsForValue().get(key);
        return "value is "+ o;
    }
}

RedisTemplate是容器里已经初始化好的对象,可以通过它来操控,其中会提供很多opsForXXX的方法,其中ops实际上就是Operations的意思,这里用opsForValue去操作字符串相关数据

此时其实已经可以开始测试了,但是由于默认自动装配的redis对编码的配置上并不友好,所以可能存在一些编码格式导致读写不符合预期的问题,编写一个Redis配置类,做一些json格式化的方案

package cn.mgl.rds.configuration;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();

        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 配置 ObjectMapper 的可见性,以便其可以访问所有成员变量(包括私有变量),即使这些变量没有公共的 getter 或 setter 方法
        // PropertyAccessor.ALL:表示所有类型的成员(字段、getter、setter、creator)。
        // JsonAutoDetect.Visibility.ANY:表示所有的成员都应该是可见的。

        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        // 启用默认类型信息,以便在序列化和反序列化时包含对象的类型信息。这样在反序列化时,Jackson 可以正确地重建对象的类型
        // LaissezFaireSubTypeValidator.instance:这是一个类型验证器,允许所有子类型。它在 Jackson 2.10 之后被引入,作为 @JsonTypeInfo 的一个安全性改进
        // ObjectMapper.DefaultTyping.NON_FINAL:仅对非最终类启用类型信息,也就是说,对于不能被继承的最终类,不会启用类型信息
        // JsonTypeInfo.As.PROPERTY:将类型信息作为属性包含在 JSON 数据中
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        // 设置key的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // 设置Hash key的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // 设置value的序列化方式
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // 设置hash value的序列化方式
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        // spring会调用这个方法来完成RedisTemplate的初始化过程,执行这个方法确保配置生效
        template.afterPropertiesSet();

        return template;
    }
}

这里通过自己生成一个Bean来覆盖默认配置,各种配置的说明都在代码注释中了,核心就是用StringRedisSerializer对各种键进行序列化,用Jackson2JsonRedisSerializer来对各种值进行序列化,并且配置了ObjectMapper来支持json的序列化和反序列化

最后,再编写一个工具类来简化操作,这样就不需要每次都操作RedisTemplate,只举例读取键和设置健值对

package cn.mgl.rds.util;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Redis工具类
 */
@Component
public class RedisUtil {
    private final RedisTemplate<String, Object> redisTemplate;

    public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 根据Key获取值
     *
     * @param key 给定键
     * @return key对应值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 将key,value放入缓存
     *
     * @param key   键
     * @param value 值
     */
    public void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 将key,value放入缓存
     *
     * @param key   键
     * @param value 值
     */
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 将key,value放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  过期时间,-1则表示不过期
     */
    public void set(String key, String value, long time) {
        if (time > 0) {
            redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
        } else {
            redisTemplate.opsForValue().set(key, value);
        }
    }
}

现在开始进行测试,先调用一次设置相关的接口,这里返回1说明设置成功了

Springboot操作Redis 接着再调用根据键获取数据的接口,可以看到也是成功获取到了刚才设置的10022

Springboot操作Redis

开启链接池提高性能

springboot2.x默认使用Lettuce客户端来链接Redis服务,默认不使用链接池,只有在配置了redis.lettuce.pool属性后才可以使用链接池,同时要引入依赖commons-pool2

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

接着添加redis链接池相关配置,为了方便改成了yaml

server:
  port: 8080

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password:
    database: 0
    lettuce:
      pool:
        max-active: 20
        max-idle: 10
        min-idle: 5
        max-wait: 5000ms
  • max-active:限制同时从连接池中获取的最大连接数,超过这个数值后,新请求会被阻塞,直到有连接被归还到池中
  • max-idel:控制连接池中空闲连接的最大数量,如果空闲连接数超过这个值,多余的空闲连接将会被销毁
  • min-idle:确保连接池中最少有多少个空闲连接。这些空闲连接会在后台不断补充,确保始终有一定数量的空闲连接可用
  • max-wait:在请求连接时,如果没有可用连接,最大等待时间是 5000 毫秒(即 5 秒)。如果在这个时间内还是无法获取连接,就会抛出异常

还需要解决下redis一些默认配置导致无法用其他网络连接的问题

如何找到mac下通过brew安装的redis的配置文件所在

先通过brew list redis找到redis的目录

Springboot操作Redis

接着查看homebrew.mxcl.redis.plist这个文件中ProgramArguments下的配置,图中红框就是配置文件地址所在

Springboot操作Redis

  • 通过任意方式进行修改文件,把bind 127.0.0.1 ::1这一行注释,表示接受外来地址
  • 再把protected-mode yes改成no(默认是yes),表示取消保护模式

Springboot操作Redis

重启下服务brew services restart redis

最后给出一个利用redis工具类的使用
package cn.mgl.rds.demos.web;

import cn.mgl.rds.util.RedisUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("redis")
public class RedisController {
    private final RedisUtil redisUtil;

    public RedisController(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    @GetMapping("setSome")
    public Object setSome(String key, String value) {
        redisUtil.set(key, value);
        return "设置成功";
    }

    @GetMapping("getSome")
    public Object getSome(String key, HttpServletRequest request) {
        Object o = redisUtil.get(key);
        return "设置成功,值为:" + o;
    }
}

完:)

转载自:https://juejin.cn/post/7384633860519051316
评论
请登录