zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    WF4.0 Beta1 自定义跟踪
    WF4.0 Beta1 流程设计器与Activity Designer
    新版本工作流平台的 (二) 权限算法(组织结构部分)
    WF4.0 Beta1 WorkflowInvoker
    WF4.0 基础篇 (十) Collection 集合操作
    WF4.0 基础篇 (十五) TransactionScope 事物容器
    WF4.0 基础篇 (六) 数据的传递 Arguments 参数
    WF4B1 的Procedural Activity 之InvokeMethod , InvokeMethod<T> 使用
    WF4.0 Beta1 异常处理
    WF4.0 Beta1 变量 Variables
  • 原文地址:https://www.cnblogs.com/coder-lichao/p/10889457.html
Copyright © 2011-2022 走看看