springboot2 配置redis,RedisTemplate,RedisCache

本文详细介绍SpringBoot2如何整合Redis,包括配置pom.xml、application.yml,以及编写RedisConfiguration类来定制缓存策略。同时,提供了UserService类使用@Cacheable和@CacheEvict注解进行缓存操作,以及RedisService类作为Redis工具类的使用示例。

springboot1.5的版本redis客户端默认是jedis,2.0以上版本默认是lettuce

本文采用lettuce,就是把application.yml配置文件里的jedis换成lettuce,

一、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.urthink.upfs</groupId>
    <artifactId>upfs-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>upfs-provider</name>
    <description>Upfs provider project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <!--去掉springboot本身日志依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--log4j2-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- 要用redis连接池 必须有pool依赖-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>com.urthink.upfs</groupId>
            <artifactId>upfs-model</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

二、application.yml

max-wait和timeout要写单位,否则提示错误redis timeout Value '2000' is not a valid duration

spring:
  redis:
    # Redis数据库索引(默认为0)
    database: 10
    # Redis服务器地址
    host: 192.168.203.220
    # Redis服务器连接端口
    port: 6379
    # Redis服务器连接密码(默认为空)
    password:
    lettuce:
      pool:
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 200
        # 连接池中的最大空闲连接
        max-idle: 20
        # 连接池中的最小空闲连接
        min-idle: 10
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
    # 连接超时时间(毫秒)默认是2000ms
    timeout: 2000ms

三、RedisConfiguration.java

这个类主要是做一些配置,没有这个类,下面的3个测试类也能跑通,

package com.urthink.upfs.provider.config;

import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;
import java.net.UnknownHostException;
import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * redis配置器
 * 参考:RedisAutoConfiguration
 * @author zhao
 * @date 2019.1.16
 */
@Configuration
@EnableCaching
public class RedisConfiguration extends CachingConfigurerSupport {

    //@Autowired
    //private RedisConnectionFactory redisConnectionFactory;


    @Bean   //在没有指定缓存Key的情况下,key生成策略
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... 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();
            }
        };
    }

    @Bean
    public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
        //spring cache注解序列化配置
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getKeySerializer()))        //key序列化方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()))    //value序列化方式
                .disableCachingNullValues()         //不缓存null值
                .entryTtl(Duration.ofSeconds(60));  //默认缓存过期时间

        // 设置一个初始化的缓存名称set集合
        Set<String> cacheNames =  new HashSet<>();
        cacheNames.add("user");

        // 对每个缓存名称应用不同的配置,自定义过期时间
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("user", redisCacheConfiguration.entryTtl(Duration.ofSeconds(120)));

        RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisTemplate.getConnectionFactory())
                .cacheDefaults(redisCacheConfiguration)
                .transactionAware()
                .initialCacheNames(cacheNames)  // 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
                .withInitialCacheConfigurations(configMap)
                .build();
        return redisCacheManager;
    }

//    @Bean
//    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
//        // 初始化缓存管理器,在这里我们可以缓存的整体过期时间等
//        // 生成一个默认配置,通过config对象即可对缓存进行自定义配置
//        //RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
//        //config = config.entryTtl(Duration.ofSeconds(60))    // 设置缓存的默认过期时间,也是使用Duration设置
//        //        .disableCachingNullValues();                // 不缓存空值
//        //RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory).cacheDefaults(config).build();
//        RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory).build();
//        return redisCacheManager;
//    }


    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        // 配置redisTemplate
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        //设置序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//      ObjectMapper om = new ObjectMapper();
//      om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); //{"id":"1","name":"张三","age":18}
////    om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);   //json数据带类的名称 //["com.urthink.upfs.model.entity.User",{"id":"1","name":"张三","age":18}]
//      jackson2JsonRedisSerializer.setObjectMapper(om);
        RedisSerializer stringSerializer = new StringRedisSerializer();

        redisTemplate.setKeySerializer(stringSerializer);                   // key序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);      // value序列化
        redisTemplate.setHashKeySerializer(stringSerializer);               // Hash key序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);  // Hash value序列化
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

三、测试类

1.User.java

package com.urthink.upfs.model.entity;

import lombok.Data;

import java.io.Serializable;

/**
 * 实体类
 */
@Data
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private String id;
    private String name;
    private int age;

}

2.UserService.java,spring boot cache注解

package com.urthink.upfs.provider.service;

import com.urthink.upfs.model.entity.User;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Cacheable(value="user", key="#id") //user::0
    public User getUser(String id) {
        System.out.println(id+"进入实现类获取数据!");
        User user = new User();
        user.setId(id);
        user.setName("张三");
        user.setAge(18);
        return user;
    }

    @CacheEvict(value="user", key="#id", condition="#id!='1'")
    public void deleteUser(String id) {
        System.out.println(id+"进入实现类删除数据!");
    }

}

3.RedisService.java,redis 工具类,可以不用

package com.urthink.upfs.provider.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

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

/**
 * redis 工具类
 */
@Component
public class RedisService<HK, V> {

    // 在构造器中获取redisTemplate实例, key(not hashKey) 默认使用String类型
    private RedisTemplate<String, V> redisTemplate;
    // 在构造器中通过redisTemplate的工厂方法实例化操作对象
    private HashOperations<String, HK, V> hashOperations;
    private ListOperations<String, V> listOperations;
    private ZSetOperations<String, V> zSetOperations;
    private SetOperations<String, V> setOperations;
    private ValueOperations<String, V> valueOperations;

    // IDEA虽然报错,但是依然可以注入成功, 实例化操作对象后就可以直接调用方法操作Redis数据库
    @Autowired
    public RedisService(RedisTemplate<String, V> redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.hashOperations = redisTemplate.opsForHash();
        this.listOperations = redisTemplate.opsForList();
        this.zSetOperations = redisTemplate.opsForZSet();
        this.setOperations = redisTemplate.opsForSet();
        this.valueOperations = redisTemplate.opsForValue();
    }


    public void hashPut(String key, HK hashKey, V value) {
        hashOperations.put(key, hashKey, value);
    }

    public Map<HK, V> hashFindAll(String key) {
        return hashOperations.entries(key);
    }

    public V hashGet(String key, HK hashKey) {
        return hashOperations.get(key, hashKey);
    }

    public void hashRemove(String key, HK hashKey) {
        hashOperations.delete(key, hashKey);
    }

    public Long listPush(String key, V value) {
        return listOperations.rightPush(key, value);
    }

    public Long listUnshift(String key, V value) {
        return listOperations.leftPush(key, value);
    }

    public List<V> listFindAll(String key) {
        if (!redisTemplate.hasKey(key)) {
            return null;
        }
        return listOperations.range(key, 0, listOperations.size(key));
    }

    public V listLPop(String key) {
        return listOperations.leftPop(key);
    }

    public void setValue(String key, V value) {
        valueOperations.set(key, value);
    }

    public void setValue(String key, V value, long timeout) {
        ValueOperations<String, V> vo = redisTemplate.opsForValue();
        vo.set(key, value, timeout, TimeUnit.MILLISECONDS);
    }


    public V getValue(String key) {
        return valueOperations.get(key);
    }

    public void remove(String key) {
        redisTemplate.delete(key);
    }

    public boolean expire(String key, long timeout, TimeUnit timeUnit) {
        return redisTemplate.expire(key, timeout, timeUnit);
    }
}

4.RedisTemplateTest.java

使用StringRedisTemplate,RedisTemplate<String, String>,RedisTemplate<Object, Object>都可以

package com.urthink.upfs.provider;

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.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.concurrent.TimeUnit;

/**
 * redisTemplate测试
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTemplateTest {

    @Autowired
    //private StringRedisTemplate redisTemplate;
    private RedisTemplate<String, String> redisTemplate;
    //private RedisTemplate<Object, Object> redisTemplate;

    @Test
    public void testRedisTemplate(){
        redisTemplate.opsForValue().set("test2","ddd",50, TimeUnit.SECONDS);
        System.out.println(redisTemplate.opsForValue().get("test2"));
    }
}

5.RedisCacheTest

package com.urthink.upfs.provider;


import com.urthink.upfs.model.entity.User;
import com.urthink.upfs.provider.service.UserService;
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.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * SpringBoot缓存注解测试
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisCacheTest {

    @Autowired
    private StringRedisTemplate template;

    @Autowired
    private UserService userService;


    @Test
    public void getUser() {
        for (int i = 0; i < 5; i++) {
            User user = userService.getUser(String.valueOf(i));
            System.out.println(user);
        }
    }

    @Test
    public void deleteUser() {
        for (int i = 0; i < 5; i++) {
            userService.deleteUser(String.valueOf(i));
        }
    }
}

6.RedisServiceTest.java

package com.urthink.upfs.provider;

import com.urthink.upfs.provider.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.SpringRunner;

/**
 * RedisService测试
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisServiceTest {
    @Autowired
    RedisService redisService;

    @Test
    public void setTest()  {
        redisService.setValue("key","hello");
    }

    @Test
    public void getTest()  {
        System.out.println("getTest:"+ redisService.getValue("key"));
    }

}

redis里的键值
user::1
{"id":"1","name":"张三","age":18}

键上为什么带两个冒号::?

RedisCache类createCacheKey方法
CacheKeyPrefix接口

   /**
     * Creates a default {@link CacheKeyPrefix} scheme that prefixes cache keys with {@code cacheName} followed by double
     * colons. A cache named {@code myCache} will prefix all cache keys with {@code myCache::}.
     *
     * @return the default {@link CacheKeyPrefix} scheme.
     */
    static CacheKeyPrefix simple() {
        return name -> name + "::";
    }

 

参考:

spring boot2 集成Redis
https://www.cnblogs.com/antball/p/9239663.html

SpringBoot 2.X集成Redis(Lettuce)
https://blog.youkuaiyun.com/lx1309244704/article/details/80696235

SpringBoot2整合Redis缓存
https://blog.youkuaiyun.com/zsj777/article/details/80801824

SpringBoot2.0.3 Redis缓存 @Cacheable、@CacheEvict、@CachePut
https://blog.youkuaiyun.com/u010588262/article/details/81003493

史上最全面的Spring Boot Cache使用与整
https://www.cnblogs.com/yueshutong/p/9381540.html

 

 

 

<think>我们正在处理用户关于Spring Boot项目中配置Redis参数的详细请求。根据用户提供的引用内容,我们可以整合信息,提供一个全面的配置指南。 引用[1]提到了Redis主从模式的配置,但用户没有特别提到主从,所以我们将以单机配置为主,同时可能简要提及主从配置(如果用户需要的话)。 引用[2]提供了依赖引入和基本的YAML配置,包括连接池配置。 引用[3]提供了通过Java配置类自定义RedisTemplate的示例。 用户请求的是“详细介绍”,因此我们将覆盖以下方面: 1. 引入依赖 2. 基本的配置文件(application.yml)中的Redis连接参数配置 3. 连接池配置(使用Jedis或Lettuce) 4. 自定义RedisTemplate(序列化方式等) 5. 使用RedisTemplate操作Redis 注意:用户没有指定Redis模式(单机、主从、集群),所以默认按单机配置。如果用户需要主从,我们可以根据引用[1]简单提及,但用户问题中没有明确要求,所以以单机为主。 由于用户要求详细介绍,我们将分步骤说明,并给出代码示例。 步骤: 1. 添加依赖 2. 配置文件(application.yml)中的Redis配置 3. 自定义RedisTemplate(可选,但推荐设置序列化方式) 4. 使用RedisTemplate 我们将按照这个结构进行回答。 </think>### Spring Boot项目配置Redis参数详细介绍 在Spring Boot中配置Redis参数主要涉及依赖配置、连接参数设置、序列化定制和连接池优化。以下是详细步骤: #### 1. 添加Redis依赖 在`pom.xml`中引入核心依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 如需使用缓存抽象层,额外添加: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> ``` #### 2. 配置文件参数(application.yml) 在配置文件中设置Redis连接参数: ```yaml spring: redis: host: 127.0.0.1 # Redis服务器IP port: 6379 # 端口号 password: yourpassword # 访问密码(无密码则留空) database: 0 # 数据库索引(0-15) timeout: 5000ms # 连接超时时间 lettuce: # 或使用jedis pool: max-active: 8 # 最大活跃连接数 max-idle: 8 # 最大空闲连接数 min-idle: 2 # 最小空闲连接数 max-wait: 1000ms # 获取连接最大等待时间 ``` #### 3. 自定义RedisTemplate(Java配置类) 默认JDK序列化效率低,建议自定义序列化方式: ```java @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); // 设置Key序列化为String template.setKeySerializer(RedisSerializer.string()); // 设置Value序列化为JSON template.setValueSerializer(RedisSerializer.json()); // 设置HashKey/HashValue序列化 template.setHashKeySerializer(RedisSerializer.string()); template.setHashValueSerializer(RedisSerializer.json()); return template; } } ``` #### 4. 主从模式配置(可选) 若需配置主从复制,在配置文件中指定节点: ```yaml spring: redis: sentinel: master: mymaster # 主节点名称 nodes: # 哨兵节点列表 - 192.168.1.101:26379 - 192.168.1.102:26379 - 192.168.1.103:26379 ``` #### 5. 使用RedisTemplate操作Redis 注入模板并执行操作: ```java @Autowired private RedisTemplate<String, Object> redisTemplate; public void demo() { // 存储字符串 redisTemplate.opsForValue().set("key", "value"); // 存储对象 User user = new User("John", 30); redisTemplate.opsForValue().set("user:1", user); // 获取对象 User cachedUser = (User) redisTemplate.opsForValue().get("user:1"); } ``` #### 关键配置说明 - **连接池参数**:`max-active`建议设为服务器核心数×2,`max-idle`应`max-active`一致[^2] - **序列化选择**:优先使用`RedisSerializer.json()`替代默认JDK序列化,节省50%以上空间[^3] - **连接超时**:生产环境建议设为1000-3000ms,避免网络波动导致线程阻塞 - **SSL支持**:通过`spring.redis.ssl=true`启用加密连接 > 最佳实践:使用`@Cachable`注解简化缓存操作,结合`spring.cache.type=redis`启用声明式缓存[^2]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值