• springboot2.x整合redis实现缓存(附github链接)


    本文代码已提交github:    https://github.com/LCABC777/Springboot-redis
    (1)Springboot中使用redis操作的两种方式:lettuce和jedis,两者在进行操作时都需要序列化器来实现序列化

    (推荐使用jackson2JsonRedisSerializer,相比于JDK提供的序列化器和String序列化器长度更短),

    lettuce和redis都是 redis的客户端。

    (2)Springboot 1.x整合Spring-data-redis底层用的是jedis,Springboot 2.x整合spring-data-redis用的是lettuce,

    jedis在多线程环境下是非线程安全的,使用了jedis pool连接池,为每个Jedis实例增加物理连接。

    Lettuce的连接是基于Netty的,连接实例(StatefulRedisConnection)可以在多个线程间并发访问。

    本文的基本环境:
      springboot: 2.x
      redis版本:redis 3.0.0
      linux系统:centos 6.5  
      jdk:1.8     
    (1)添加maven依赖
    <!--web依赖-->
    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
    <!--redis依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency> <!--junit依赖-->
    <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
    <!--spring test测试依赖> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
     (2)application.properties中redis数据源及lettuce客户端配置
    #redis
    # 连接设置
    spring.redis.database=0
    spring.redis.host=192.168.18.128
    spring.redis.port=6379
    spring.redis.password=123456
    spring.redis.timeout=10000ms
    # 连接池设置
    spring.redis.lettuce.pool.max-idle=8
    spring.redis.lettuce.pool.max-wait=
    spring.redis.lettuce.pool.min-idle=0
    spring.redis.lettuce.pool.max-active=8

         (3)redis模板(redisTemplate,提供对redis数据库的操作方法)及缓存管理器(cacheManager)配置

    package com.lc.config;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.cache.interceptor.KeyGenerator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.*;
    import javax.annotation.Resource;
    import java.time.Duration;
    import java.util.HashMap;
    import java.util.Map;
    
    
    @Configuration
    public class RedisConfig {
      
      //lettuce客户端连接工厂 @Resource
    private LettuceConnectionFactory lettuceConnectionFactory;
      //日志
    private Logger logger=LoggerFactory.getLogger(RedisConfig.class);
      //json序列化器
    private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //缓存生存时间 private Duration timeToLive = Duration.ofDays(1);
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
         //redis缓存配置 RedisCacheConfiguration config
    = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(this.timeToLive) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())) .disableCachingNullValues();
         //缓存配置map Map
    <String,RedisCacheConfiguration> cacheConfigurationMap=new HashMap<>();
         //自定义缓存名,后面使用的@Cacheable的CacheName cacheConfigurationMap.put(
    "users",config); cacheConfigurationMap.put("default",config);
         //根据redis缓存配置和reid连接工厂生成redis缓存管理器 RedisCacheManager redisCacheManager
    = RedisCacheManager.builder(connectionFactory) .cacheDefaults(config) .transactionAware() .withInitialCacheConfigurations(cacheConfigurationMap) .build(); logger.debug("自定义RedisCacheManager加载完成"); return redisCacheManager; }

      //redisTemplate模板提供给其他类对redis数据库进行操作 @Bean(name
    = "redisTemplate") public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){ RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); redisTemplate.setKeySerializer(keySerializer()); redisTemplate.setHashKeySerializer(keySerializer()); redisTemplate.setValueSerializer(valueSerializer()); redisTemplate.setHashValueSerializer(valueSerializer()); logger.debug("自定义RedisTemplate加载完成"); return redisTemplate; }
      
      
      //redis键序列化使用StrngRedisSerializer
    private RedisSerializer<String> keySerializer() { return new StringRedisSerializer(); }
      

      //redis值序列化使用json序列化器
    private RedisSerializer<Object> valueSerializer() { return new GenericJackson2JsonRedisSerializer(); }   

      //缓存键自动生成器 @Bean
    public KeyGenerator myKeyGenerator() { return (target, method, params) -> { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); }; } }

    (4)利用redisTemplate进行对redis数据库的操作

     注入redisTemplate

     @Autowired
     private RedisTemplate redisTemplate;

    (5)使用redis的hash来存储map,并做缓存处理,用来验证是否成功

    //添加hash,需要hash名和存储的键值对Map  
    public
    void setHash(String hashName,Map<String,String> map) { redisTemplate.opsForHash().putAll(hashName,map); }   
      //Springboot的启动器main方法上需要加上@EnableCaching开启缓存,使用了@Cacheable注解后,缓存的值将被存入redis数据库中
      //缓存名可以为RedisConfig中自定义的缓存名,键生成器为RedisConig中自定义的键生成器,也可以自己自定义缓存key名 @Cacheable(cacheNames
    = "users",keyGenerator ="myKeyGenerator")
    //从redis中获取map
    public Map<Object,Object> getHash(String hashName){ if (redisTemplate.hasKey(hashName)) { System.out.println(redisTemplate.opsForHash().entries(hashName)); return redisTemplate.opsForHash().entries(hashName); }else { return null; } }

    (6)使用junit来测试缓存

    import com.lc.Starter;
    import com.lc.service.RedisService;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import java.util.HashMap;
    import java.util.Map;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = Starter.class)
    public class MyTest {
        @Autowired
        private RedisService redisService;
        
        @Test
        public void hashTest(){
            Map<String,String> map=new HashMap<>();
            map.put("a879","1");
            map.put("2131","23");
         //redis中添加hash redisService.setHash(
    "ccc",map);
         //多次获取hash Map hash
    =redisService.getHash("ccc"); redisService.getHash("ccc");
         redisService.getHash("ccc")
    if (hash!=null){ System.out.println(hash.toString()); } } }

    (7)多次获取hash,测试结果只执行了两次打印方法,说明除了第一次都是从redis的缓存库中读取的缓存,而不是getHash中的redisTemplate.opsForHash().entries(hashName)

    (8)从redisDesktop中可以清楚的看到redis的存储,setHash方法将ccc这个hash存入了redis库中,而getHash方法做缓存处理后,程序直接将包名+方法名+参数这个由keyGenertor自动生成的字符串作为key, Geneic json序列化器将要缓存类型在java中的包名和缓存的值组成json串作为value实现了缓存

    本文代码已提交github:    https://github.com/LCABC777/Springboot-redis

  • 相关阅读:
    Nginx日志管理
    Nginx负载均衡
    Nginx 缓存
    Nginx代理服务器
    Nginx搭建 Web服务
    Nginx HTTP模块
    洛谷P1012拼数
    洛谷 P1876 开灯
    洛谷P2084 进制转化
    关于typedef的用法
  • 原文地址:https://www.cnblogs.com/coder-lichao/p/10889457.html
Copyright © 2020-2023  润新知