SpringBoot集成Redis,springcloud原理面试题

本文详细介绍了如何在SpringBoot中整合Redis,包括使用Lettuce替换Jedis,配置RedisTemplate,以及解决序列化问题。通过配置文件设置Redis连接参数,创建RedisTemplate Bean,并自定义序列化方式以避免转义字符问题。此外,还展示了如何创建一个工具类简化Redis操作,并提供了相关面试题及学习资源。
摘要由CSDN通过智能技术生成

首先,先查看Redis相关的配置类:

在这里插入图片描述

shift+shift进行搜索,查看RedisAutoConfiguration类:

在这里插入图片描述

在我们查看redis的配置类RedisAutoConfiguration时,可以看到RedisAutoConfiguation中封装了两个Bean:

在这里插入图片描述

接下来查看redis所对应的自动配置类:RedisProperties,该类对应一个properties配置文件,当然我们也可以在application中进行配置:

在这里插入图片描述

在SpringBoot操作数据是封装在Spring-data中的,jpa、jdbc、mongodb、redis,而在SpringBoot2.x以后与原来使用的jedis被替换成来看lettuce,底层已经不使用jedis了

  • jedis: 采用的直连,多个线程操作的话,不安全,要提高安全性要使用jedis pool连接池
  • lettuce: 采用netty,高性能网络框架,异步请求,实例在多线程中可以共享,不存在线程不安全的情况,dubbo底层也是用netty,可以减少线程数量,更像NIO模式

[](

)整合实现


导入依赖pom.xml:


<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-data-redis</artifactId>

</dependency>

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-web</artifactId>

</dependency> 

编写配置文件applacation.yml:


spring:

    redis:

      host: 127.0.0.1 # Redis服务器地址

      port: 6379 # Redis服务器连接端口

      password:    # Redis服务器连接密码(默认为空)

      database: 0 # Redis数据库索引(默认为0)

      jedis:

        pool:

          max-active: 8 # 连接池最大连接数(使用负值表示没有限制)

          max-wait: -1ms  # 连接池最大阻塞等待时间(使用负值表示没有限制)

          max-idle: 500 # 连接池中的最大空闲连接

          min-idle: 0 # 连接池中的最小空闲连接

      lettuce:

        shutdown-timeout: 0ms

      timeout: 1000 # 连接超时时间(毫秒) 

测试:


@SpringBootTest

public class SpringbootRedisTest {



    @Autowired

    private RedisTemplate<String,String> redisTemplate;



    @Test

    void contextLoads() {

        redisTemplate.opsForValue().set("key1","value1");

        redisTemplate.opsForValue().set("key2","张三");

        System.out.println("key1="+redisTemplate.opsForValue().get("key1"));

        System.out.println("key2="+redisTemplate.opsForValue().get("key2"));

    }



} 

运行结果:

在这里插入图片描述

查看RedisTemplate类:

在这里插入图片描述

测试代码:


@Test

public void test() throws JsonProcessingException {

    //真实开发一般有使用json传递对象

    User user =new User();

    user.setName("龙源");

    user.setAge(10);

    String jsonUser = new ObjectMapper().writeValueAsString(user);

    redisTemplate.opsForValue().set("user",jsonUser);

    System.out.println(redisTemplate.opsForValue().get("user"));

}



//新建一个User类

@Component

public class User implements Serializable {//需要序列化Serializable

    private String name;

    private int age;

    

    /**

     * Get,Set,toString

     **/

} 

运行结果:

在这里插入图片描述

在客户端进行查看:发现user对象前面有转义字符

在这里插入图片描述

[](

)序列化


编写配置类,自定义RedisTemplate,修改默认的序列化方式:


@Configuration

public class RedisConfig {



  @Bean

  @SuppressWarnings("all")

  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

      //为了方便开发,使用<String,Object>

      RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();

      template.setConnectionFactory(factory);

      

      //Json序列化配置

      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);

      

      //String的序列化

      StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();



      // key采用String的序列化方式

      template.setKeySerializer(stringRedisSerializer);

      // hash的key也采用String的序列化方式

      template.setHashKeySerializer(stringRedisSerializer);

      // value序列化方式采用jackson

      template.setValueSerializer(jackson2JsonRedisSerializer);

      // hash的value序列化方式采用jackson

      template.setHashValueSerializer(jackson2JsonRedisSerializer);

      template.afterPropertiesSet();



      return template;

  }



} 

再次测试:


//为了方便识别可以修改:RedisTemplate

@Autowired

//private RedisTemplate redisTemplate;

private RedisTemplate<String,Object> redisTemplate;



@Test

public void test() throws JsonProcessingException {

    //真实开发一般有使用json传递对象

    User user =new User();

    user.setName("龙源");

    user.setAge(10);

    String jsonUser = new ObjectMapper().writeValueAsString(user);

    redisTemplate.opsForValue().set("user",jsonUser);

    System.out.println(redisTemplate.opsForValue().get("user"));

} 

运行结果:

在这里插入图片描述

自定义工具类:

在真实开发中,一般不会使用原生的API而是使用自己封装的工具类RedisUtil


@Component

public final class RedisUtil {



    @Autowired

    private RedisTemplate<String, Object> redisTemplate;



    // =============================common============================

    /**

     * 指定缓存失效时间

     * @param key  键

     * @param time 时间(秒)

     */

    public boolean expire(String key, long time) {

        try {

            if (time > 0) {

                redisTemplate.expire(key, time, TimeUnit.SECONDS);

            }

            return true;

        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }

    }



    /**

     * 根据key 获取过期时间

     * @param key 键 不能为null

     * @return 时间(秒) 返回0代表为永久有效

     */

    public long getExpire(String key) {

        return redisTemplate.getExpire(key, TimeUnit.SECONDS);

    }



    /**

     * 判断key是否存在

     * @param key 键

     * @return true 存在 false不存在

     */

    public boolean hasKey(String key) {

        try {

            return redisTemplate.hasKey(key);

        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }

    }



    /**

     * 删除缓存

     * @param key 可以传一个值 或多个

     */

    @SuppressWarnings("unchecked")

    public void del(String... key) {

        if (key != null && key.length > 0) {

            if (key.length == 1) {

                redisTemplate.delete(key[0]);

            } else {

                redisTemplate.delete(CollectionUtils.arrayToList(key));

            }

        }

    }



    // ============================String=============================

    /**

     * 普通缓存获取

     * @param key 键

     * @return 值

     */

    public Object get(String key) {

        return key == null ? null : redisTemplate.opsForValue().get(key);

    }



    /**

     * 普通缓存放入

     * @param key   键

     * @param value 值

     * @return true成功 false失败

     */

    public boolean set(String key, Object value) {

        try {

            redisTemplate.opsForValue().set(key, value);

            return true;

        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }

    }



    /**

     * 普通缓存放入并设置时间

     * @param key   键

     * @param value 值

     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期

     * @return true成功 false 失败

     */

    public boolean set(String key, Object value, long time) {

        try {

            if (time > 0) {

                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);

            } else {

                set(key, value);

            }

            return true;

        } catch (Exception e) {

            e.printStackTrace();

            return false;

        }

    }



    /**

     * 递增

     * @param key   键

     * @param delta 要增加几(大于0)

     */

    public long incr(String key, long delta) {

        if (delta < 0) {

            throw new RuntimeException("递增因子必须大于0");

        }

        return redisTemplate.opsForValue().increment(key, delta);

    }



    /**

     * 递减

     * @param key   键

     * @param delta 要减少几(小于0)

     */

    public long decr(String key, long delta) {

        if (delta < 0) {

            throw new RuntimeException("递减因子必须大于0");

        }

        return redisTemplate.opsForValue().increment(key, -delta);

    }



    // ================================Map=================================



    /**

     * HashGet

     * @param key  键 不能为null

     * @param item 项 不能为null

     */

    public Object hget(String key, String item) {

        return redisTemplate.opsForHash().get(key, item);

    }



    /**

     * 获取hashKey对应的所有键值

     * @param key 键

     * @return 对应的多个键值

     */

    public Map<Object, Object> hmget(String key) {

        return redisTemplate.opsForHash().entries(key);

    }



    /**

     * HashSet

     * @param key 键

     * @param map 对应多个键值

     */

    public boolean hmset(String key, Map<String, Object> map) {

        try {

            redisTemplate.opsForHash().putAll(key, map);

            return true;

        } catch (Exception e) {

            e.printStackTrace();

            return false;


# 分享

这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](

)**

![薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了](https://img-blog.csdnimg.cn/img_convert/cad22362bfb22263318f2a46d1426d3b.png)

Spring Cloud实战

![薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了](https://img-blog.csdnimg.cn/img_convert/4e43803fe491fb4b9c58cdee2946ac10.png)

Spring Boot实战

![薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了](https://img-blog.csdnimg.cn/img_convert/09887395d9391a8799dcbc210ea93f84.png)

y);

    }



    /**

     * HashSet

     * @param key 键

     * @param map 对应多个键值

     */

    public boolean hmset(String key, Map<String, Object> map) {

        try {

            redisTemplate.opsForHash().putAll(key, map);

            return true;

        } catch (Exception e) {

            e.printStackTrace();

            return false;


# 分享

这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](

)**

[外链图片转存中...(img-YlEo6KhH-1631183146003)]

Spring Cloud实战

[外链图片转存中...(img-11ap1uJO-1631183146005)]

Spring Boot实战

[外链图片转存中...(img-0mE4EGko-1631183146006)]

面试题整理(性能优化+微服务+并发编程+开源框架+分布式)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值