芋道 Spring Boot Redis 入门(上)

开源项目芋道源码解析 [开篇] 文章首发于我的博客:https://blog.liuzijian.com/post/source-code-about-ruoyi-vue-pro.html芋道(又名yudao,ruoyi-vue-pro)是一个基于spring-boot框架的单体Java后端开源项目,拥有基于RBAC模型的组织架构管理、CRM、ERP、商城、代码生成、AI等多个功能模块。封装了多租户、数据权限、工作流、OAuth,邮件、短信、定时任务、日志、链路追踪等多种技术和业务组件。其在GitHub上的地址是:https://gith 阅读详情

点击上方“芋道源码

做积极的人,而不是积极废人!

源码精品专栏

 

摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/Redis/ 「芋道源码」欢迎转载,保留摘要,谢谢!

  • 1. 概述

  • 2. 快速入门

    • 2.1 引入依赖

    • 2.2 配置文件

    • 2.3 简单测试

    • 2.4 RedisTemplate

  • 3. 序列化

    • 3.1 RedisSerializer

    • 3.2 配置序列化方式

    • 3.3 自定义 RedisSerializer 实现类


1. 概述

在快速入门 Spring Boot 整合 Redis 之前,我们先来做个简单的了解。在 Spring 的生态中,我们使用 Spring Data Redis 来实现对 Redis 的数据访问。

可能这个时候,会有胖友会有疑惑,市面上已经有 Redis、Redisson、Lettuce 等优秀的 Java Redis 工具库,为什么还要有 Spring Data Redis 呢?学不动了,头都要秃了!不要慌,我们先来看一张图:

640?wx_fmt=png
Spring Data Redis 调用
  • 对于下层,Spring Data Redis 提供了统一的操作模板(后文中,我们会看到是 RedisTemplate 类),封装了 Jedis、Lettuce 的 API 操作,访问 Redis 数据。所以,实际上,Spring Data Redis 内置真正访问的实际是 Jedis、Lettuce 等 API 操作。

  • 对于上层,开发者学习如何使用 Spring Data Redis 即可,而无需关心 Jedis、Lettuce 的 API 操作。甚至,未来如果我们想将 Redis 访问从 Jedis 迁移成 Lettuce 来,无需做任何的变动。😈 相信很多胖友,在选择 Java Redis 工具库,也是有过烦恼的。

  • 目前,Spring Data Redis 暂时只支持 Jedis、Lettuce 的内部封装,而 Redisson 是由 redisson-spring-data 来提供。

OK ,哔哔结束,我们先来快速上手下 Spring Data Redis 的使用。

2. 快速入门

示例代码对应仓库:spring-data-redis-with-jedis 。

在 spring-boot-starter-data-redis 项目 2.X 中,默认使用 Lettuce 作为 Java Redis 工具库,猜测是因为 Jedis 中间有一段时间诈尸,基本不太更新。

感兴趣的胖友可以看看 https://mvnrepository.com/artifact/redis.clients/jedis 地址,会发现 2016 年到 2018 年的 Jedis 更新频率。所幸,2018 年底又突然复活了。

考虑到自己项目中,使用 Jedis 为主,并且问了几个朋友,都是使用 Jedis ,并且有吐槽 Lettuce 坑多多,所以个人推荐的话,生产中还是使用 Jedis ,稳定第一。也因此,本节我们是 Spring Data Redis + Jedis 的组合。

同时,艿艿目前使用的 SkyWalking 中间件,暂时只支持 Jedis 的自动化的追踪,那么更加考虑使用 Jedis 啦。

这里在分享一个 Jedis 和 Lettuce 的对比讨论。

2.1 引入依赖

在 pom.xml 文件中,引入相关依赖。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>

    <!-- 实现对 Spring Data Redis 的自动化配置 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <exclusions>
            <!-- 去掉对 Lettuce 的依赖,因为 Spring Boot 优先使用 Lettuce 作为 Redis 客户端 -->
            <exclusion>
                <groupId>io.lettuce</groupId>
                <artifactId>lettuce-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- 引入 Jedis 的依赖,这样 Spring Boot 实现对 Jedis 的自动化配置 -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>

    <!-- 方便等会写单元测试 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- 等会示例会使用 fastjson 作为 JSON 序列化的工具 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.61</version>
    </dependency>

    <!-- Spring Data Redis 默认使用 Jackson 作为 JSON 序列化的工具 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>

</dependencies>

具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

2.2 配置文件

在 application.yml 中,添加 Redis 配置,如下:

spring:
  # 对应 RedisProperties 类
  redis:
    host: 127.0.0.1
    port: 6379
    password: # Redis 服务器密码,默认为空。生产中,一定要设置 Redis 密码!
    database: 0 # Redis 数据库号,默认为 0 。
    timeout: 0 # Redis 连接超时时间,单位:毫秒。
    # 对应 RedisProperties.Jedis 内部类
    jedis:
      pool:
        max-active: 8 # 连接池最大连接数,默认为 8 。使用负数表示没有限制。
        max-idle: 8 # 默认连接数最小空闲的连接数,默认为 8 。使用负数表示没有限制。
        min-idle: 0 # 默认连接池最小空闲的连接数,默认为 0 。允许设置 0 和 正数。
        max-wait: -1 # 连接池最大阻塞等待时间,单位:毫秒。默认为 -1 ,表示不限制。

具体每个参数的作用,胖友自己认真看下艿艿添加的所有注释噢。

2.3 简单测试

创建 Test01 测试类,我们来测试一下简单的 SET 指令。代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class Test01 {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void testStringSetKey() {
        stringRedisTemplate.opsForValue().set("yunai", "shuai");
    }
}

通过 StringRedisTemplate 类,我们进行了一次 Redis SET 指令的执行。关于 StringRedisTemplate 是什么,我们先卖个关子,在 「2.4 RedisTemplate」 中来介绍。

我们先来执行下 #testStringSetKey() 方法这个测试方法。执行完成后,我们在控制台查询,看看是否真的执行成功了。

$ redis-cli get yunai
"shuai"
  • 请大声的告诉我,Redis 是怎么夸奖 "yunai" 的,哈哈哈哈。

2.4 RedisTemplate

org.springframework.data.redis.core.RedisTemplate<K, V> 类,从类名上,我们就明明白白知道,提供 Redis 操作模板 API 。核心属性如下:

// RedisTemplate.java
// 艿艿省略了一些不重要的属性。

// <1> 序列化相关属性
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer keySerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer valueSerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashKeySerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashValueSerializer = null;
private RedisSerializer<String> stringSerializer = RedisSerializer.string();

// <2> Lua 脚本执行器
private @Nullable ScriptExecutor<K> scriptExecutor;

// <3> 常见数据结构操作类
// cache singleton objects (where possible)
private @Nullable ValueOperations<K, V> valueOps;
private @Nullable ListOperations<K, V> listOps;
private @Nullable SetOperations<K, V> setOps;
private @Nullable ZSetOperations<K, V> zSetOps;
private @Nullable GeoOperations<K, V> geoOps;
private @Nullable HyperLogLogOperations<K, V> hllOps;
  • <1> 处,看到了四个序列化相关的属性,用于 KEY 和 VALUE 的序列化。

    • 例如说,我们在使用 POJO 对象存储到 Redis 中,一般情况下,会使用 JSON 方式序列化成字符串,存储到 Redis 中。详细的,我们在 「3. 序列化」 小节中来说明。

    • 在上文中,我们看到了 `org.springframework.data.redis.core.StringRedisTemplate` 类,它继承 RedisTemplate 类,使用 `org.springframework.data.redis.serializer.StringRedisSerializer` 字符串序列化方式。直接点开 StringRedisSerializer 源码,看下它的构造方法,瞬间明明白白。

  • <2> 处,Lua 脚本执行器,提供 Redis scripting API 操作。

  • <3> 处,Redis 常见数据结构操作类。

    • ValueOperations 类,提供 Redis String API 操作。

    • ListOperations 类,提供 Redis List API 操作。

    • SetOperations 类,提供 Redis Set API 操作。

    • ZSetOperations 类,提供 Redis ZSet(Sorted Set) API 操作。

    • GeoOperations 类,提供 Redis Geo API 操作。

    • HyperLogLogOperations 类,提供 Redis HyperLogLog API 操作。

那么 Pub/Sub、Transaction、Pipeline、Keys、Cluster、Connection 等相关的 API 操作呢?它在 RedisTemplate 自身提供,因为它们不属于具体每一种数据结构,所以没有封装在对应的 Operations 类中。哈哈哈,胖友打开 RedisTemplate 类,去瞅瞅,妥妥的明白。

3. 序列化

艿艿:为了尽量把序列化说的清楚一些,所以本小节内容会略长。

因为有些地方,直接撸源码,比吓哔哔一段话更易懂,所以会有一些源码,保持淡定。

3.1 RedisSerializer

org.springframework.data.redis.serializer.RedisSerializer 接口,Redis 序列化接口,用于 Redis KEY 和 VALUE 的序列化。简化代码如下:

// RedisSerializer.java
public interface RedisSerializer<T> {

    @Nullable
    byte[] serialize(@Nullable T t) throws SerializationException;

    @Nullable
    T deserialize(@Nullable byte[] bytes) throws SerializationException;

}
  • 定义了对象 和二进制数组的转换。

  • 啊,可能有胖友会有疑惑了:我们在 redis-cli 终端,看到的不都是字符串么,怎么这里是序列化成二进制数组呢?实际上,Redis Client 传递给 Redis Server 是传递的 KEY 和 VALUE 都是二进制值数组。好奇的胖友,可以打开 Jedis `Connection#sendCommand(final Command cmd, final byte[]… args)` 方法,传入的参数就是二进制数组,而 cmd 命令也会被序列化成二进制数组。

RedisSerializer 的实现类,如下图:

640?wx_fmt=png
Spring Data Redis 调用

主要分成四类:

  • JDK 序列化方式

  • String 序列化方式

  • JSON 序列化方式

  • XML 序列化方式

3.1.1 JDK 序列化方式

org.springframework.data.redis.serializer.JdkSerializationRedisSerializer ,默认情况下,RedisTemplate 使用该数据列化方式。具体的,可以看看 RedisTemplate#afterPropertiesSet() 方法,在 RedisTemplate 未设置序列化的情况下,使用 JdkSerializationRedisSerializer 作为序列化实现。在 Spring Boot 自动化配置 RedisTemplate Bean 对象时,就未设置。

绝大多数情况下,可能 99.9999% ,我们不会使用 JdkSerializationRedisSerializer 进行序列化。为什么呢?我们来看一个示例,代码如下:

// Test01.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class Test01 {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testStringSetKey02() {
        redisTemplate.opsForValue().set("yunai", "shuai");
    }

}

我们先来执行下 #testStringSetKey02() 方法这个测试方法。注意,此处我们使用的是 RedisTemplate 而不是 StringRedisTemplate 。执行完成后,我们在控制台查询,看看是否真的执行成功了。

# 在 `redis-cli` 终端中

127.0.0.1:6379> scan 0
1) "0"
2) 1) "\xac\xed\x00\x05t\x00\x05yunai"

127.0.0.1:6379> get "\xac\xed\x00\x05t\x00\x05yunai"
"\xac\xed\x00\x05t\x00\x05shuai"
  • 通过 Redis SCAN 命令,我们扫描出了一个奇怪的 "yunai" KEY ,前面带着奇怪的 16 进制字符。而后,我们使用这个奇怪的 KEY 去获取对应的 VALUE ,结果前面也是一串奇怪的 16 进制字符。

    具体为什么是这样一串奇怪的 16 进制,胖友可以看看 ObjectOutputStream#writeString(String str, boolean unshared) 的代码,实际就是标志位 + 字符串长度 + 字符串内容。

对于 KEY 被序列化成这样,我们线上通过 KEY 去查询对应的 VALUE 势必会非常不方便,所以 KEY 肯定是不能被这样序列化的。

对于 VALUE 被序列化成这样,除了阅读可能困难一点,不支持跨语言外,实际上也没啥问题。不过,实际线上场景,还是使用 JSON 序列化居多。

3.1.2 String 序列化方式

① org.springframework.data.redis.serializer.StringRedisSerializer ,字符串和二进制数组的直接转换。代码如下:

// StringRedisSerializer.java

private final Charset charset;

@Override
public String deserialize(@Nullable byte[] bytes) {
    return (bytes == null ? null : new String(bytes, charset));
}

@Override
public byte[] serialize(@Nullable String string) {
    return (string == null ? null : string.getBytes(charset));
}
  • 是不是很直接简单。

绝大多数情况下,我们 KEY 和 VALUE 都会使用这种序列化方案。而 VALUE 的序列化和反序列化,自己在逻辑调用 JSON 方法去序列化。为什么呢?继续往下看。

② org.springframework.data.redis.serializer.GenericToStringSerializer<T> ,使用 Spring ConversionService 实现 <T> 对象和 String 的转换,从而 String 和二进制数组的转换。

例如说,序列化的过程,首先 <T> 对象通过 ConversionService 转换成 String ,然后 String 再序列化成二进制数组。反序列化的过程,胖友自己结合源码思考下 🤔 。

当然,GenericToStringSerializer 貌似基本不会去使用,所以不用去了解也问题不大,哈哈哈。

3.1.3 JSON 序列化方式

① org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer ,使用 Jackson 实现 JSON 的序列化方式,并且从 Generic 单词可以看出,是支持所有类。怎么体现呢?参见构造方法的代码:

// GenericJackson2JsonRedisSerializer.java

public GenericJackson2JsonRedisSerializer(@Nullable String classPropertyTypeName) {

    this(new ObjectMapper());

    // simply setting {@code mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)} does not help here since we need
    // the type hint embedded for deserialization using the default typing feature.
    mapper.registerModule(new SimpleModule().addSerializer(new NullValueSerializer(classPropertyTypeName)));

    // <1>
    if (StringUtils.hasText(classPropertyTypeName)) {
        mapper.enableDefaultTypingAsProperty(DefaultTyping.NON_FINAL, classPropertyTypeName);
    // <2>
    } else {
        mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
    }
}
  • <1> 处,如果传入了 classPropertyTypeName 属性,就是使用使用传入对象的 classPropertyTypeName 属性对应的值,作为默认类型(Default Typing)。

  • <2> 处,如果未传入 classPropertyTypeName 属性,则使用传入对象的类全名,作为默认类型(Default Typing)。

那么,胖友可能会问题,什么是默认类型(Default Typing)呢?我们来思考下,在将一个对象序列化成一个字符串,怎么保证字符串反序列化成对象的类型呢?Jackson 通过 Default Typing ,会在字符串多冗余一个类型,这样反序列化就知道具体的类型了。来举个例子,使用我们等会示例会用到的 UserCacheObject 类。

  • 标准序列化的结果,如下:

    {
        "id": 1,
        "name": "芋道源码",
        "gender": 1
    }
    
  • 使用 Jackson Default Typing 机制序列化的结果,如下:

     {
            "@class": "cn.iocoder.springboot.labs.lab10.springdatarediswithjedis.cacheobject.UserCacheObject",
            "id": 1,
            "name": "芋道源码",
            "gender": 1
        }
    
    • 看 @class 属性,反序列化的对象的类型不就有了么?

下面我们来看一个 GenericJackson2JsonRedisSerializer 的示例。在看之前,胖友先跳到 「3.2 配置序列化方式」 小节,来看看如何配置 GenericJackson2JsonRedisSerializer 作为 VALUE 的序列化方式。然后,马上调回到此处。

示例代码如下:

// Test01.java

@Autowired
private RedisTemplate redisTemplate;

@Test
public void testStringSetKeyUserCache() {
    UserCacheObject object = new UserCacheObject()
            .setId(1)
            .setName("芋道源码")
            .setGender(1); // 男
    String key = String.format("user:%d", object.getId());
    redisTemplate.opsForValue().set(key, object);
}

@Test
public void testStringGetKeyUserCache() {
    String key = String.format("user:%d", 1);
    Object value = redisTemplate.opsForValue().get(key);
    System.out.println(value);
}

胖友分别执行 #testStringSetKeyUserCache() 和 #testStringGetKeyUserCache() 方法,然后对着 Redis 的结果看看,比较简单,就不多哔哔了。

我们在回过头来看看 @class 属性,它看似完美解决了反序列化后的对象类型,但是带来 JSON 字符串占用变大,所以实际项目中,我们也并不会采用 Jackson2JsonRedisSerializer 类。

② org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer<T> ,使用 Jackson 实现 JSON 的序列化方式,并且显示指定 <T> 类型。代码如下:

// Jackson2JsonRedisSerializer.java
public class Jackson2JsonRedisSerializer<T> implements RedisSerializer<T> {
    // ... 省略不重要的代码

    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

    /**
     * 指定类型,和 <T> 要一致。
     */
    private final JavaType javaType;

    private ObjectMapper objectMapper = new ObjectMapper();

}

因为 Jackson2JsonRedisSerializer 序列化类里已经声明了类型,所以序列化的 JSON 字符串,无需在存储一个 @class 属性,用于存储类型。

但是,我们抠脚一想,如果使用 Jackson2JsonRedisSerializer 作为序列化实现类,那么如果我们类型比较多,岂不是每个类型都要定义一个 RedisTemplate Bean 了?!所以实际场景下,我们也并不会使用 Jackson2JsonRedisSerializer 类。😈

③ com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer ,使用 FastJSON 实现 JSON 的序列化方式,和 GenericJackson2JsonRedisSerializer 一致,就不重复赘述。

注意,GenericFastJsonRedisSerializer 不是 Spring Data Redis 内置实现,而是由于 FastJSON 自己实现。

④ com.alibaba.fastjson.support.spring.FastJsonRedisSerializer<T> ,使用 FastJSON 实现 JSON 的序列化方式,和 Jackson2JsonRedisSerializer 一致,就不重复赘述。

注意,GenericFastJsonRedisSerializer 不是 Spring Data Redis 内置实现,而是由于 FastJSON 自己实现。

3.1.4 XML 序列化方式

org.springframework.data.redis.serializer.OxmSerializer ,使用 Spring OXM 实现将对象和 String 的转换,从而 String 和二进制数组的转换。

因为 XML 序列化方式,暂时没有这么干过,我自己也没有,所以就直接忽略它吧。😝

3.2 配置序列化方式

创建 RedisConfiguration 配置类,代码如下:

@Configuration
public class RedisConfiguration {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 创建 RedisTemplate 对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置 RedisConnection 工厂。😈 它就是实现多种 Java Redis 客户端接入的秘密工厂。感兴趣的胖友,可以自己去撸下。
        template.setConnectionFactory(factory);

        // 使用 String 序列化方式,序列化 KEY 。
        template.setKeySerializer(RedisSerializer.string());

        // 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
        template.setValueSerializer(RedisSerializer.json());
        return template;
    }

}
  • RedisSerializer#string() 静态方法,返回的就是使用 UTF-8 编码的 StringRedisSerializer 对象。代码如下:

    // RedisSerializer.java
    static RedisSerializer<String> string() {
        return StringRedisSerializer.UTF_8;
    }
    
    // StringRedisSerializer.java
    public static final StringRedisSerializer ISO_8859_1 = new StringRedisSerializer(StandardCharsets.ISO_8859_1);
    
  • RedisSerializer#json() 静态方法,返回 GenericJackson2JsonRedisSerializer 对象。代码如下:

    // RedisSerializer.java
    
    static RedisSerializer<Object> json() {
        return new GenericJackson2JsonRedisSerializer();
    }
    

3.3 自定义 RedisSerializer 实现类

我们直接以 GenericFastJsonRedisSerializer 举例子,直接莽源码。代码如下:

// GenericFastJsonRedisSerializer.java

public class GenericFastJsonRedisSerializer implements RedisSerializer<Object> {
    private final static ParserConfig defaultRedisConfig = new ParserConfig();
    static { defaultRedisConfig.setAutoTypeSupport(true);}

    public byte[] serialize(Object object) throws SerializationException {
        // 空,直接返回空数组
        if (object == null) {
            return new byte[0];
        }
        try {
            // 使用 JSON 进行序列化成二进制数组,同时通过 SerializerFeature.WriteClassName 参数,声明写入类全名。
            return JSON.toJSONBytes(object, SerializerFeature.WriteClassName);
        } catch (Exception ex) {
            throw new SerializationException("Could not serialize: " + ex.getMessage(), ex);
        }
    }

    public Object deserialize(byte[] bytes) throws SerializationException {
        // 如果为空,则返回空对象
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        try {
            // 使用 JSON 解析成对象。
            return JSON.parseObject(new String(bytes, IOUtils.UTF8), Object.class, defaultRedisConfig);
        } catch (Exception ex) {
            throw new SerializationException("Could not deserialize: " + ex.getMessage(), ex);
        }
    }
}

完成自定义 RedisSerializer 配置类后,我们就可以参照 「3.2 配置序列化方式」 小节,将 VALUE 序列化的修改成我们的,哈哈哈。



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:

640?wx_fmt=jpeg

已在知识星球更新源码解析如下:

如果你喜欢这篇文章,喜欢,转发。

生活很美好,明天见(。・ω・。)ノ♡

芋道源码 —— Spring Boot 缓存 Cache 入门 随着系统访问量的增加,数据库往往成为性能瓶颈。为了减少数据库的压力,提高系统的响应速度,我们可以通过缓存来优化系统性能。 阅读详情

相关推荐

芋道框架万字详解(前后端分离)、若依框架、yudao-cloud保姆级攻略

芋道开发框架,低代码平台

争者留其名 2万+

芋道源码 yudao-cloud:构建全功能后台管理系统的技术探索

芋道,以开发者为中心,打造中国第一流的快速开发平台,全部开源,个人与企业可 100% 免费使用。master分支为 JDK 8 + Spring Boot 2.7,分支为 JDK 17/21 + Spring Boot 3.2管理后台的电脑端:Vue3 提供 element-plus、vben(ant-design-vue) 两个版本,Vue2 提供 element-ui 版本管理后台的移动端:采用 uni-app 方案,一份代码多终端适配,同时支持 APP、小程序、H5!

chenchuang0128的博客 1万+

ruoyi-vue-pro-vben 芋道管理后台,基于 vben 最新版本

ruoyi-vue-pro-vben 芋道管理后台,基于 vben 最新版本,最新的 vue3 vite4 ant-design-vue 4.0 typescript 语法进行重构开发,支持 springboot3 springcloud 版本

Java开发框架选型对比:ruoyi与yudao框架

web项目基础框架研究,含主流框架对比与使用分享

lili1158的博客 7万+

瑞芯微RK3568与RK3566芯片选型指南:从接口差异到应用场景深度解析

在嵌入式系统与边缘计算领域,芯片选型是决定产品成败的关键一步。其核心在于理解芯片的架构、接口扩展能力与系统可靠性之间的平衡。以瑞芯微(Rockchip)的RK3568和RK3566为例,这两款同为四核A55架构的芯片,在基础算力上相近,但其面向的应用赛道却因接口配置而截然不同。RK3568凭借其双千兆网口、PCIe 3.0高速接口以及全链路ECC内存支持,在技术价值上更侧重于构建高可靠、高扩展性的系统,如边缘计算网关、工业控制器和网络视频录像机(NVR)。相比之下,RK3566则以其精简的接口配置,精准服务

weixin_33314040的博客 482

软考29-上午题-【数据结构】-排序

数据结构7种排序

qq_31532983的博客 1580

芋道微服务功能介绍(限免)

芋道 Spring Cloud是一款国产的SpringCloud微服务框架,包括Outh2.0、微服务网关、微服务注册中心、配置中心、消息队列、任务调度、链路追踪、服务保障等。上一章节我们进度,我们已经把后端系统API、后台管理系统(Vue3版本)运行起来了,今天我们介绍下这些大致的功能。这一章节就讲解到这里,我们做了后台管理系统登录流程拆解,看到了页面跳转、后端API调用、接口Debug、页面数据交互等。下一章节, 我们继续介绍其他功能。

Java 技术专栏,从入门到精通,熟悉企业级开发 1万+

某10kV纺织厂供电系统设计【CAD图纸源码+Word文档】

本文详细介绍了设计变电所原始资料,负荷统计,基于负荷统计给出了变压器的选型,变电所主接线方式的设计、高低压母线、电缆的技术要求、短路电流的计算以及相关电气设备的保护参数及保护定值的计算、安全措施的规定。

weixin_761237174的博客 2744

芋道 Spring Boot Redis 入门

摘要: 原创出处http://www.iocoder.cn/Spring-Boot/Redis/「芋道源码」欢迎转载,保留摘要,谢谢! 1. 概述 2. 快速入门 3. 序列化 4. 项目实践 5. 示例补充 6. 尝试 Redisson 666. 彩蛋 本文在提供完整代码示例,可见https://github.com/YunaiV/SpringBoot-Labs的lab-11-spring-data-redis目录。 原创不易,给点个Star嘿,一起冲鸭! 1. 概述...

YHJ 5650

从手机到单片机:聊聊ARM Cortex家族那些事,A、R、M系列到底有啥不同?

本文深入解析ARM Cortex家族的A、R、M三大系列处理器,揭示它们在性能、实时响应和能效方面的核心差异。从智能手机到汽车电子和物联网设备,Cortex-A、R、M各司其职,分别应对复杂运算、实时控制和超低功耗场景。通过技术指标对比和典型应用案例,帮助开发者理解如何根据DMIPS/MHz等关键参数选择适合的处理器架构。

weixin_31574149的博客 351

若依框架集成saToken

若依版本3.8.8,鉴权采用security框架,这种框架太重,项目中想实现对外提供接口功能。尽快减少修改原框架的逻辑基础上,采用satoken实现。

sccd2009的专栏 1483

芋道 Spring Boot Redis 入门(下)

点击上方“芋道源码做积极的人,而不是积极废人!源码精品专栏摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/Redis/ 「芋道源码」欢迎转载,保留摘要,谢谢!4. 项目实践4.1 Cache Object4.2 数据访问层4.3 序列化5. 示例补充5.1 Pipeline5.2 Transaction5.3 Session5.4 Pub/Sub5.5 Sc...

芋艿V 505

团体程序设计天梯赛竞赛题--登顶题【L3-042 污染大亨】

登顶级 3 道题,每道题 30 分,满分为 90 分。

Pretty Boy Fox的博客 1361

Spring Boot整合Redis

Redis 基于内存进行存储,支持key-value的存储形式,底层是用C语言进行编写的 基于key-value形式的数据字典,结构简单,没有数据表的概念,直接用键值对形式完成数据的管理。 支持5种数据类型: 字符串 列表 集合 有序集合 哈希 搭建Redis环境 在windows上安装Redis 下载Redis https://github.com/MicrosoftArchive/redis/tags 如不能进入Github,可以到https://download.youkuaiyun.com/downl

zjojk的博客 1万+

2026华为OD面试题029:勇攀数字高峰

在给定的数字地形图里寻找登山路径,数字代表当前位置的海拔高度。要求从最低海拔出发,不断攀登,最终到达最高山峰。地图保证最低海拔和最高山峰都只有一个。 登山规则: - 路径上的海拔必须严格递增 - 只能向上下左右 4 个方向移动 - 路径必须从最低海拔开始,到最高海拔结束 - 每个地点只能走一次 - 每一步的攀登高度差必须大于 0,且不超过指定值 `K` 输出满足条件的登山路径的数量。

琅嬛福地 123

如何让C++程序生成dump文件?生成dump文件的方式有哪些?如何使用Windbg分析dump文件?

本文详细介绍了如何让C++程序生成dump文件、生成dump文件的多种方式以及如何使用Windbg分析dump文件,并给出了对应的实战分析案例,有一定的实战参考价值。

dvlinker的技术专栏 5万+

芋道源码:企业级Spring Boot开发框架实战指南

### 1.1 框架选型困惑破解 在众多Java开发框架中,如何找到既满足企业级需求又保持开发效率的解决方案?芋道源码作为一款开箱即用的Spring Boot框架,通过模块化设计和预置业务组件,帮助开发者在30分钟内搭建起企业级应用骨架,解决传统开发中"重复造轮子"的痛点。 ### 1.2 核心能力对比 | 特性 | 芋道源码 | 传统Spring Boot | 其他企业级框架 | |-----

gitblog_01169的博客 782

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Redis Java 集成到 Spring Boot

Redis Java 集成到 Spring Boot(基本练习)

明志の博客 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

3步精通芋道源码:从零构建企业级Spring Boot应用实战指南

想要快速掌握企业级Spring Boot应用开发?芋道源码项目为你提供了完整的实战解决方案!这份终极指南将带你从零开始,在3个简单步骤中构建出功能完善的企业级应用。🚀 ## 什么是芋道源码项目? 芋道源码是一个基于Spring Boot的企业级开发框架,集成了权限管理、工作流、数据报表等核心功能。它采用模块化设计,让开发者能够快速搭建符合企业需求的应用系统。 [![芋道源码企业级应用架构]

gitblog_00008的博客 1081

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

芋道源码企业级框架从入门到精通完整指南

芋道源码作为一款基于Spring Boot深度优化的企业级应用框架,为开发者提供了开箱即用的完整解决方案。无论你是刚接触企业级开发的新手,还是希望提升开发效率的资深工程师,本指南都将带你全面掌握这个强大工具。 ## 项目快速上手 ### 环境准备与源码获取 通过以下命令快速获取项目源码: ```bash git clone https://gitcode.com/gh_mirrors/ru/

gitblog_00314的博客 958

企业级Spring Boot框架开发效率提升解决方案:芋道源码全解析

芋道源码作为一款企业级Spring Boot应用框架,通过模块化开发实现业务逻辑与技术架构的解耦,为企业级应用提供从数据权限控制到工作流引擎的完整解决方案。本文将从价值定位、核心能力、实战指南和扩展进阶四个维度,全面解析芋道源码框架如何帮助开发者提升开发效率,构建稳定可靠的企业级应用。 ## 一、价值定位:3大核心优势解决企业级开发痛点 在企业级应用开发过程中,开发者常常面临系统架构复杂、模块

gitblog_00398的博客 812

芋道源码终极指南:Spring Boot企业级开发框架实战教程

芋道源码是一个基于Spring Boot的企业级开发框架,为开发者提供了一套完整的企业应用解决方案。这个开源项目涵盖了从基础架构到业务模块的全方位功能,是快速构建企业级应用的理想选择。 ## 🚀 什么是芋道源码? 芋道源码是一个功能丰富的Spring Boot企业级开发框架,它整合了现代企业应用所需的各种核心组件和技术栈。无论是中小型企业还是大型互联网公司,都能从这个框架中找到适合自己业务场

gitblog_00830的博客 943

芋道源码:企业级Spring Boot应用框架的终极指南

芋道源码是一个功能强大的企业级Spring Boot应用框架,专为Java开发者提供完整的后端解决方案。这个开源框架集成了现代化企业应用所需的各种功能模块,让开发者能够快速构建高质量的业务系统。😊 ## 🚀 框架核心架构与设计理念 芋道源码采用**模块化架构设计**,将不同的业务功能拆分成独立的模块,每个模块都包含API接口和业务实现两部分。这种设计让系统更加灵活,便于维护和扩展。 ##

gitblog_00109的博客 802

芋道 Spring Boot 缓存 Cache 入门

点击上方“芋道源码”,选择“设为星标”做积极的人,而不是积极废人!源码精品专栏原创 | Java 2019 超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络...

芋艿V 403

芋道 Spring Boot JPA 入门(一)之快速入门

点击上方“芋道源码”,选择“设为星标”做积极的人,而不是积极废人!源码精品专栏原创 | Java 2019 超神之路,很肝~中文详细注释的开源项目分布式复习--RPC框架Dubbo 二...

芋艿V 440
上一篇: 狗屎一样的代码!快,重构我!
下一篇: 感受 Java Lambda 之美,推荐收藏,需要时查阅
公众号-芋道源码
博客等级 码龄10年 1636粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值