美文网首页
SpringBoot中集成Redis

SpringBoot中集成Redis

作者: 花醉霜寒 | 来源:发表于2020-05-16 16:50 被阅读0次

    \color{green}{添加pom依赖}
    此处需要更新jackson的版本,否则会报错

    NoClassDefFoundError: com/fasterxml/jackson/databind/ObjectMapper
    
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.11.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>2.11.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>2.11.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>3.3.0</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    

    \color{green}{配置文件配置}

    spring:
      redis:
        # Redis数据库索引(默认为0)
        database: 0
        # Redis服务器地址
        host: localhost
        # Redis服务器连接端口
        port: 6379
    
        lettuce:
          pool:
            max-active: 8
            max-wait: -1
            max-idle: 8
            min-idle: 0
    

    JedisPool的主要可选参数及参数含义如下所示:

    public abstract class BaseObjectPoolConfig extends BaseObject implements Cloneable {
    
        //当资源池连接用尽后,调用者的最大等待时间(ms),默认值为-1,表示永不超时
        private long maxWaitMillis = DEFAULT_MAX_WAIT_MILLIS;
    
        //资源池中资源的最小空闲时间(ms),达到此值后空闲资源将被移除,默认值为1000L * 60L * 30L(30min)
        private long minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    
        //连接空闲时间大于softMinEvictableIdleTimeMillis并且当前连接池的空闲连接数大于最小空闲连接数minIdle,默认值为-1,表示永不超时
        private long softMinEvictableIdleTimeMillis = DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    
        //空闲资源检测时,每次检测资源的个数。默认值为3,设置为-1表示对所有资源进行检测
        private int numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
    
        //是否开启空闲资源检测,默认值为false,建议设置为true
        private boolean testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
    
        //空闲资源的检测周期(单位为毫秒),默认值为-1,表示不检测,建议开启检测,建议设置为30s左右
        private long timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
    
        //当资源池用尽后,调用者是否要等待。只有当值为true时,下面的maxWaitMillis才会生效
        private boolean blockWhenExhausted = DEFAULT_BLOCK_WHEN_EXHAUSTED;
    
        //是否开启JMX监控
        private boolean jmxEnabled = DEFAULT_JMX_ENABLE;
    }
    
    
    public class GenericObjectPoolConfig extends BaseObjectPoolConfig {
    
        //资源池中的最大连接数,默认值为8
        private int maxTotal = DEFAULT_MAX_TOTAL;
    
        //资源池允许的最大空闲连接数,默认值为8
        private int maxIdle = DEFAULT_MAX_IDLE;
    
        //资源池确保的最少空闲连接数,默认值为0
        private int minIdle = DEFAULT_MIN_IDLE;
    }
    

    \color{green}{配置类}
    1)spring-boot-starter-data-redis 1.x 传统写法

    @Configuration
    @EnableCaching
    public class MyRedisConfig extends CachingConfigurerSupport {
        @Value("${spring.redis.host}")
        private String redisHost;
        @Value("${spring.redis.port}")
        private Integer redisPort;
        @Value("${spring.redis.pool.max-active}")
        private int maxActive;
        @Value("${spring.redis.pool.min-idle}")
        private int minIdle;
        @Value("${spring.redis.pool.max-idle}")
        private int maxIdle;
        @Value("${spring.redis.pool.max-wait}")
        private int maxWait;
    
        @Bean("queryManager")
        @Primary
        public CacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) {
            RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
            cacheManager.setDefaultExpiration(1800L);
            return cacheManager;
        }
    
        @Bean
        public JedisConnectionFactory jedisConnectionFactory() {
            JedisPoolConfig pooConfig = new JedisPoolConfig();
            // 最大空闲连接数, 默认8个
            pooConfig.setMaxIdle(maxIdle);
            // 最大连接数, 默认8个
            pooConfig.setMaxTotal(maxActive);
            // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,
            // 默认-1
            pooConfig.setMaxWaitMillis(maxWait);
            // 最小空闲连接数, 默认0
            pooConfig.setMinIdle(minIdle);
            JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
            redisConnectionFactory.setHostName(redisHost);
            redisConnectionFactory.setPort(redisPort);
            redisConnectionFactory.setPoolConfig(pooConfig);
            redisConnectionFactory.setPassword(password);
            redisConnectionFactory.setDatabase(database);
            return redisConnectionFactory;
        }
        @Bean
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
            JedisConnectionFactory jedisConnectionFactory = (JedisConnectionFactory) redisConnectionFactory;
            redisTemplate.setConnectionFactory(jedisConnectionFactory);
            redisTemplate.setEnableTransactionSupport(false);
            RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(stringRedisSerializer);
            redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            redisTemplate.setHashKeySerializer(stringRedisSerializer);
            redisTemplate.setHashValueSerializer(stringRedisSerializer);
            return redisTemplate;
        }
       
        @Override
        public KeyGenerator keyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object target, Method method, Object... params) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("wiki-");
                    sb.append(target.getClass().getName());
                    sb.append(".");
                    sb.append(method.getName());
                    sb.append("(");
                    return sb.append(StringUtils.join(params, ",")).append(")").toString();
                }
            };
        }
    }
    

    但是JedisConnectionFactory中很多方法都被废弃了,不推荐使用,需要使用新版本使用全新的实现方式。


    2)spring-boot-starter-data-redis 2.x版本写法

    • 配置IP和端口号
    @Configuration
    @ConfigurationProperties(prefix = "spring.redis")
    @ConditionalOnProperty(name = {"spring.redis.host"})
    @Data
    public class StandaloneRedisConfig {
    
        private String host;
    
        private int port;
    }
    
    • 配置JedisPool
    @Configuration
    @ConfigurationProperties(prefix = "spring.redis.lettuce.pool")
    @Data
    public class JedisPoolConfig {
    
        private int maxActive;
    
        private int maxWait;
    
        private int maxIdle;
    
        private int minIdle;
    }
    
    • 配置RedisTemplate
    @Configuration
    @EnableCaching
    public class RedisConfig {
    
        @Autowired
        StandaloneRedisConfig standaloneRedisConfig;
    
        @Autowired
        JedisPoolConfig jedisPoolConfig;
    
        @Bean
        @ConditionalOnBean(value = {StandaloneRedisConfig.class})
        public RedisConnectionFactory standaloneRedisConnectionFactory() {
            //此处可以使用默认的JedisPool,new RedisStandaloneConfiguration(standaloneRedisConfig);
            //如果如果想要自己配置JedisPool的参数可以这样使用
            return new JedisConnectionFactory(new RedisStandaloneConfiguration(standaloneRedisConfig.getHost(), standaloneRedisConfig.getPort()), clientConfiguration());
        }
    
        @Bean
        @ConditionalOnBean(value = {JedisPoolConfig.class})
        public JedisClientConfiguration clientConfiguration() {
            //配置JedisClientConfiguration并指定JedisPool
            JedisClientConfiguration.JedisClientConfigurationBuilder builder = JedisClientConfiguration.builder();
            return builder.usePooling()
                    .poolConfig(poolConfig(jedisPoolConfig))
                    .build();
        }
    
        private GenericObjectPoolConfig poolConfig(JedisPoolConfig config) {
            GenericObjectPoolConfig jedisPool = new GenericObjectPoolConfig();
            jedisPool.setMaxIdle(config.getMaxIdle());
            jedisPool.setMinIdle(config.getMinIdle());
            jedisPool.setMaxTotal(config.getMaxActive());
            return jedisPool;
        }
    
        @Bean("redisTemplate")
        public RedisTemplate<Object, Object> redisTemplate() {
            RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
            RedisConnectionFactory connectionFactory = standaloneRedisConnectionFactory();
            redisTemplate.setConnectionFactory(connectionFactory);
            redisTemplate.setEnableTransactionSupport(false);
            RedisSerializer<String> stringRedisSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(stringRedisSerializer);
            redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            redisTemplate.setHashKeySerializer(stringRedisSerializer);
            redisTemplate.setHashValueSerializer(stringRedisSerializer);
            return redisTemplate;
        }
    
    
    /**
         * 配置jedisPool
         * @return JedisPool
         */
        @Bean("jedisPool")
        public JedisPool createJedis() {
            return new JedisPool(poolConfig(jedisPoolConfig), standaloneRedisConfig.getHost(), standaloneRedisConfig.getPort());
        }
    
    
    
        @Bean
        public SpringConfigProvider springConfigProvider() {
            return new SpringConfigProvider();
        }
    
        /**
         * 配置jetcache
         * @return GlobalCacheConfig
         */
        @Bean("globalCacheConfig")
        @ConditionalOnBean(value = {JedisPool.class, JedisPool.class})
        @SuppressWarnings("unchecked")
        public GlobalCacheConfig config(){
            Map localBuilders = new HashMap(8);
            EmbeddedCacheBuilder localBuilder = LinkedHashMapCacheBuilder
                    .createLinkedHashMapCacheBuilder()
                    .keyConvertor(FastjsonKeyConvertor.INSTANCE);
            localBuilders.put(CacheConsts.DEFAULT_AREA, localBuilder);
    
            Map remoteBuilders = new HashMap(8);
            RedisCacheBuilder remoteCacheBuilder = RedisCacheBuilder.createRedisCacheBuilder()
                    .keyConvertor(FastjsonKeyConvertor.INSTANCE)
                    .valueEncoder(JavaValueEncoder.INSTANCE)
                    .valueDecoder(JavaValueDecoder.INSTANCE)
                    .jedisPool(createJedis());
            remoteBuilders.put(CacheConsts.DEFAULT_AREA, remoteCacheBuilder);
    
            GlobalCacheConfig globalCacheConfig = new GlobalCacheConfig();
            globalCacheConfig.setLocalCacheBuilders(localBuilders);
            globalCacheConfig.setRemoteCacheBuilders(remoteBuilders);
            globalCacheConfig.setStatIntervalMinutes(15);
            globalCacheConfig.setAreaInCacheName(false);
            return globalCacheConfig;
        }
    
    }
    

    除了配置了RedisTemplate,还配置了JedisPool和JetCache。
    \color{green}{SpringBoot中使用Redis}
    编写测试类进行测试

    @Component
    public class CacheService {
    
    
        @Autowired
        RedisTemplate<String, String> redisTemplate;
    
        @PostConstruct
        public void test() {
            System.out.println("第一次调用");
            this.getCache("aaa");
            System.out.println("第二次调用");
            this.getCache("aaa");
        }
    
        private String getCache(String key) {
            String value = redisTemplate.opsForValue().get(key);
            if(StringUtil.isNullOrEmpty(value)) {
                System.out.println("第一次调用缓存中不存在");
                redisTemplate.opsForValue().set("aaa", "bbb");
                return "bbb";
            } else {
                System.out.println("第二次调用直接返回");
                return value;
            }
    
        }
    }
    

    输出结果为:

    第一次调用
    第一次调用缓存中不存在
    第二次调用
    第二次调用直接返回
    

    相关文章

      网友评论

          本文标题:SpringBoot中集成Redis

          本文链接:https://www.haomeiwen.com/subject/xekrohtx.html