吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1266|回复: 5
收起左侧

[Java 原创] spring boot 4整合redis

[复制链接]
vsked 发表于 2026-2-12 14:19
本帖最后由 vsked 于 2026-2-12 14:26 编辑

缓存这东西大家都知道吧。打个比方,上游一直要传一些数据,如果这些数据一直传重复的就没有什么意义。我们只保存数据变化 的时候。
这时候我们会考虑用缓存来解决,缓存有本地缓存,也有网络缓存。如果本地缓存能解决问题,那我们一般优先上本地缓存。像caffeine就是一种本地缓存。
那当数据量很大,达到百万级,或是多个应用都需要访问共同的缓存数据怎么办呢?
这时候就会用到网络缓存,比如redis就是其中的一种。
spring boot版本升级很快。我们先引入spring boot 与redis相关的jar包,还有一些单元测试的jar包
这里使用了testng作为单元测试框架,使 用了log4j2作为日志记录框架。
使用了springdatajpa来管理redis连接的相关信息

[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>

    <groupId>com.vsked</groupId>
    <artifactId>springboot4redis</artifactId>
    <version>1.0</version>

    <name>${project.artifactId}</name>

    <properties>
        <!-- 声明项目配置依赖编码格式为 utf-8 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <!-- 编译UTF-8 -->
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>

        <!-- java jdk 版本声明 可变更 根据自己配置去匹配 -->
        <java.version>21</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <maven.deploy.skip>true</maven.deploy.skip>
        <maven.install.skip>true</maven.install.skip>
        <mavenCompilerPlugin.version>3.14.0</mavenCompilerPlugin.version>
        <mavenSurefirePlugin.version>3.5.3</mavenSurefirePlugin.version>

        <testng.version>7.11.0</testng.version>
        <springboot.version>4.0.2</springboot.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${springboot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!-- spring boot devtools 第一步添加依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
            <scope>runtime</scope>
        </dependency>
        <!-- spring boot核心,包括自动配置支持日志和YAML -->
        <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>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webmvc-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 对web开发的支持包含了spring webmvc和tomcat等web开发的特性 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- TestNG start -->
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.webjars</groupId>
                    <artifactId>jquery</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- TestNG end -->
        <!-- log4j start -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
        <!-- log4j end -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${mavenCompilerPlugin.version}</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <!-- true:跳过测试 -->
                    <skip>true</skip>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${mavenSurefirePlugin.version}</version>
                <configuration>
                    <skip>true</skip>
                    <argLine>
                        -javaagent:"${settings.localRepository}/org/mockito/mockito-core/5.14.2/mockito-core-5.14.2.jar"
                    </argLine>
                </configuration>
            </plugin>
            <!-- spring boot devtools 第二步添加maven插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${springboot.version}</version>
                <configuration>
                    <mainClass>com.vsked.Application</mainClass>
                    <!--addResources如果没有该项配置,这个devtools不会起作用即应用不会restart这个要手动加进去 3.0版本用这个配置 -->
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


然后我们编写主配置文件
主配置文件作用是环境的切分这里我们激活开发环境,当然这里面也记录了redis的连接信息。比如ip,端口,密码
[Plain Text] 纯文本查看 复制代码
spring:
  profiles:
    active: dev
  lifecycle:
    timeout-per-shutdown-phase: 60s #设置优雅停机缓冲时间默认30s
  devtools:
    restart:
      enabled: true #设置开启热部署


开发环境的实际代码如下application.yml
[Plain Text] 纯文本查看 复制代码
server:
  port: 8181 #端口号
  shutdown: graceful #开启优雅停机 默认为immediate立即停机

spring:
  devtools:
    restart:
      enabled: true #设置开启热部署
  data:
    redis:
      database: 0
      host: 127.0.0.1
      port: 6379
      password: 123456789
      timeout: 10000

logging:
  config: classpath:log4j2.xml




开发环境引入了log4j2的配置文件,负责配置日志文件存储相关策略与打印策略log4j2.xml
[XML] 纯文本查看 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!--设置log4j2的自身log级别为warn-->
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,    当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="warn" monitorInterval="60">
    <Properties>
        <!--<Property name="logpath">${sys:catalina.home}/logs/mybatismutids/</Property>-->
        <Property name="logpath">/logs/springboot4redis/</Property>
        <Property name="logname">springboot4redis</Property>
    </Properties>
    <!--先定义所有的appender-->
    <appenders>
        <!--这个输出控制台的配置-->
        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} traceId:[%X{mdc_trace_id}] %-5level %class{36} %L %M - %msg%xEx%n" />
        </console>
        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
        <File name="log" fileName="${logpath}/${logname}_test" append="false">
            <PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} traceId:[%X{mdc_trace_id}] %-5level %class{36} %L %M - %msg%xEx%n" />
        </File>
        <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,
        则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileInfo" fileName="${logpath}/info_${logname}" filePattern="${logpath}/${logname}error_%d{yyyy-MM-dd}_%i.log">
            <Filters>
                <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <ThresholdFilter level="INFO"/>
                <ThresholdFilter level="WARN"/>
            </Filters>
            <PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} traceId:[%X{mdc_trace_id}] %-5level %class{36} %L %M - %msg%xEx%n" />
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
        </RollingFile>

        <RollingFile name="RollingFileWarn" fileName="${logpath}/warn_${logname}" filePattern="${logpath}/${logname}error_%d{yyyy-MM-dd}_%i.log">
            <Filters>
                <ThresholdFilter level="WARN"/>
                <ThresholdFilter level="ERROR"/>
            </Filters>
            <PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} traceId:[%X{mdc_trace_id}] %-5level %class{36} %L %M - %msg%xEx%n" />
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
            <DefaultRolloverStrategy max="20"/>
        </RollingFile>

        <RollingFile name="RollingFileError" fileName="${logpath}/error_${logname}" filePattern="${logpath}/${logname}error_%d{yyyy-MM-dd}_%i.log">
            <ThresholdFilter level="ERROR"/>
            <PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} traceId:[%X{mdc_trace_id}] %-5level %class{36} %L %M - %msg%xEx%n" />
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
        </RollingFile>
        <RollingFile name="RollingFileAll" fileName="${logpath}/All_${logname}" filePattern="${logpath}/${logname}all_%d{yyyy-MM-dd}_%i.log">
            <ThresholdFilter level="ALL"/>
            <PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} traceId:[%X{mdc_trace_id}] %-5level %class{36} %L %M - %msg%xEx%n" />
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
        </RollingFile>
    </appenders>
    <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <!--过滤掉spring和hibernate的一些无用的debug信息-->
        <logger name="org.springframework" level="ERROR"></logger>
        <logger name="org.hibernate" level="ERROR"></logger>
        <logger name="com.zaxxer" level="ERROR"></logger>
        <logger name="org.mybatis" level="ERROR"></logger>
        <logger name="io.netty" level="ERROR"></logger>
        <logger name="io.lettuce" level="ERROR"></logger>
        <logger name="org.xnio" level="ERROR"></logger>
        <logger name="org.apache" level="ERROR"></logger>
        <logger name="org.jboss" level="ERROR"></logger>
        <!-- 不打印本项目sql语句,需要时请调整为debug -->
        <logger name="com.vsked.dao" level="ALL" additivity="true"></logger>
        <root level="all">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
            <appender-ref ref="RollingFileAll"/>
        </root>
    </loggers>

</configuration>


然后编写一个redis配置的文件负责配置redisTemplate也就是初始化参数,定义序列化与反序列化的类
[Java] 纯文本查看 复制代码
package com.vsked.config;

import tools.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
class RedisConfiguration {
    @Bean
    RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();

        ObjectMapper jackson = new ObjectMapper();
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        redisTemplate.setValueSerializer(new GenericJacksonJsonRedisSerializer(jackson));
        redisTemplate.setHashValueSerializer(new GenericJacksonJsonRedisSerializer(jackson));

        //使用StringRedisSerializer来序列化和反序列化redis的ke
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        redisTemplate.setConnectionFactory(connectionFactory);
        return redisTemplate;
    }

}


然后我们写一个启动应用的程序。这个主要为单元测试作准备的.springboot 应用都会有这么一个启动应用的。
[Java] 纯文本查看 复制代码
package com.vsked;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
        
        public static void main(String[] args) {
                SpringApplication.run(Application.class, args);
        }
        
}


然后我们就可以写一个单元测试试一下啦。
先写一个单元测试基础类。
这个类负责引用刚才写的springboot启动应用,来准备单元测试
[Java] 纯文本查看 复制代码
package com.vsked.test;

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.springframework.test.context.web.WebAppConfiguration;
import com.vsked.Application;

@SpringBootTest(classes = Application.class)
@WebAppConfiguration
public class BaseTestWithoutTransactional extends AbstractTestNGSpringContextTests{

}

然后就可以使用testng配合springboot4对redis进行单元测试了
为了方便,这里还打印了redis连接的相关信息。
[Java] 纯文本查看 复制代码
package com.vsked.redis;
import com.vsked.test.BaseTestWithoutTransactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.testng.annotations.Test;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class RedisTest extends BaseTestWithoutTransactional {

    private static final Logger log = LoggerFactory.getLogger(RedisTest.class);

    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Test
    public void printConnectionInfo() {
        var factory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();

        log.info("=================== Redis Connection Info ===================");
        log.info("Host: {}:{}", factory.getHostName(), factory.getPort());
        log.info("Database: {}", factory.getDatabase());
        log.info("Password: {}", factory.getPassword());
        log.info("Timeout: {}", factory.getTimeout());
        log.info("SSL: {}", factory.isUseSsl());
        log.info("Cluster: {}", factory.getClusterConfiguration());
        // 打印连接池信息
        // 获取 Lettuce 连接池配置
        try {
            var field = factory.getClass().getDeclaredField("clientConfiguration");
            field.setAccessible(true);
            var clientConfig = field.get(factory);

            log.info("=================== Lettuce Pool Info ===================");
            log.info("Client Configuration: {}", clientConfig);
        } catch (Exception e) {
            log.error("无法获取连接池配置信息: {}", e.getMessage());
        }
        log.info("===========================================================");
    }

    @Test
    public void saveString(){
        String redisKey="springBoot4Redis:module1:userNameF1";
        String redisValue="myNameIsBruce";
        redisTemplate.opsForValue().set(redisKey,redisValue);
        log.info("{}",redisTemplate.opsForValue().get(redisKey));
    }

    @Test
    public void saveStringWithTime(){
        String redisKey="springBoot4Redis:module1:userNameF1";
        String redisValue="myNameIsBruce";
        redisTemplate.opsForValue().set(redisKey,redisValue,10,TimeUnit.MINUTES);
        log.info("{}",redisTemplate.opsForValue().get(redisKey));
    }

    @Test
    public void delString(){
        String redisKey="springBoot4Redis:module1:userNameF1";
        redisTemplate.delete(redisKey);
        log.info("{}",redisTemplate.opsForValue().get(redisKey));
    }

    @Test
    public void save2String(){
        String redisKey="springBoot4Redis:module1:userName15";
        String redisValue="myNameIsBruce5s";
        redisTemplate.opsForValue().set(redisKey,redisValue,15, TimeUnit.SECONDS);
    }

    @Test
    public void saveList(){
        String redisKey="springBoot4Redis:module1:userList1";
        List<Map<String,Object>> testDataList=new LinkedList<>();
        for(int i=0;i<10;i++){
            Map<String,Object> dataMap=new HashMap<>();
            dataMap.put("user"+i,"value"+i);
            testDataList.add(dataMap);
        }
        redisTemplate.opsForValue().set(redisKey,testDataList);
    }

    @Test
    public void getList(){
        String redisKey="springBoot4Redis:module1:userList1";
        List<Map<String,Object>> testDataList= (List<Map<String, Object>>) redisTemplate.opsForValue().get(redisKey);
        log.info("{}",testDataList);
    }

}


如果你感觉我搭建的这个springboot4整合redis的框架还不错,可以分享给你的朋友,大家一起进步吧。
所有代码都在下面附件中:

springboot4redis.zip (18.15 KB, 下载次数: 9)



免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ltysvx 发表于 2026-2-12 14:23
抓住一个水贴
 楼主| vsked 发表于 2026-2-12 14:25

我这可是最新版本spring boot4.0.2整合redis的基础框架哟。不水,不水,我没有水呀
若无zz 发表于 2026-2-12 15:14
vsked 发表于 2026-2-12 14:25
我这可是最新版本spring boot4.0.2整合redis的基础框架哟。不水,不水,我没有水呀

就这还需要看版本吗 不想说破都
 楼主| vsked 发表于 2026-2-12 15:17
若无zz 发表于 2026-2-12 15:14
就这还需要看版本吗 不想说破都

看来大佬是内行,咱不看版本,看你这头像确实挺吸引我哒
CTZ 发表于 2026-2-21 23:46
不明觉厉!支持原创!!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-8-28 00:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表