Java 项目实战: 交友项目 - 通用缓存SpringCache:介绍以及入门案例

嵌入式Linux网络调试踩坑记:YT8531/YT8521 PHY驱动移植与设备树配置实战 本文深入解析嵌入式Linux系统中YT8531/YT8521 PHY驱动移植与设备树配置的实战经验。从网络不通的常见现象入手,详细介绍了驱动移植关键点、设备树配置详解及常见问题排查技巧,帮助开发者快速解决RGMII接口调试难题,提升嵌入式网络开发效率。 阅读详情

概述

为什么需要缓存、手写缓存会踩哪些坑,在通用缓存SpringCache:问题引入中已经推导过,这里不再重复。本文解决另一个问题:不写任何缓存读写代码,只靠注解,能不能把缓存做出来。答案是 SpringCache,十秒钟就能让一个查库方法拥有缓存能力,下面从概念、注解体系到第一个可运行的案例完整走一遍。

纲要

  • SpringCache 是什么:缓存抽象层,接口与实现分离
  • 注解体系:@EnableCaching / @Cacheable / @CachePut / @CacheEvict / @Caching 速查表
  • 入门案例:引入依赖 → 开启缓存 → @Cacheable 标注方法,运行验证缓存命中
  • 底层实现切换:默认 ConcurrentMap,生产环境换 Redis
  • AOP 代理原理:为什么同类内部调用会让注解失效
  • 踩坑速查与常见误解澄清

SpringCache 是什么

SpringCache(官方名 Spring Cache,属于 spring-context-support 模块)是 Spring 提供的缓存抽象层。它利用 AOP 实现了基于注解的缓存功能:开发者只在方法上标注解声明「这个方法的结果要缓存」,至于「缓存读写到哪里、怎么存怎么取」,全部由框架的代理拦截器完成。

这里有个容易忽略的定位问题:SpringCache 本身不实现缓存。它只定义了一套接口,Cache(一次缓存操作)和 CacheManager(管理一组缓存),真正的存取动作由底层实现完成。这个「接口与实现分离」的设计带来的直接好处是:注解代码一行不改,底层可以从内存缓存换成 Redis。

业务代码
UserService.findById()

@Cacheable 注解

CacheInterceptor
(AOP 代理拦截)

CacheManager 接口

ConcurrentMapCacheManager
(默认,内存缓存)

RedisCacheManager
(生产环境常用)

JVM 内存 Map

Redis

与声明式事务 @Transactional 是同一个思想:方法级的声明式缓存。事务不用手写 commit/rollback,缓存也不用自己读写 Map,都是 AOP 代理在方法前后织入了通用逻辑。

注解体系

SpringCache 的全部日常使用就是五个注解:

注解作用典型位置注意事项
@EnableCaching开启缓存功能,没有它其余注解全部无效启动引导类只需加一次
@Cacheable先查缓存,命中直接返回;未命中执行方法并把结果放入缓存查询方法最重要的注解;value 指定命名空间(必填),key 指定缓存键(支持 SpEL)
@CachePut总是执行方法,并用返回值更新缓存写操作需要同步刷新缓存时与 @Cacheable 的本质区别:不查缓存、方法必执行
@CacheEvict清除缓存更新/删除方法key 清单个,allEntries = true 清整个命名空间
@Caching组合多个缓存注解一个方法要同时做多种缓存操作例如同时 evict 两个 key

@Cacheable 与 @CachePut 的区别值得单独记住:

对比项@Cacheable@CachePut
先查缓存?是,命中就不执行方法否
方法何时执行仅缓存未命中时每次都执行
返回值去向未命中时写入缓存总是写入缓存
适用场景查询写操作后同步缓存

@CacheEvict 的两种清除粒度:key = "#id" 只删某一条,allEntries = true 把 value 命名空间下的全部条目一次清空,列表类数据被写操作污染后往往整批失效,后者反而更常用(交友项目发布视频清空视频列表缓存就是这么做的)。

入门案例

使用 SpringCache 一共三步:引依赖 → 开启缓存 → 方法上加注解。下面配套了一个基础工程 spring-cache-demo,先看它的结构:

spring-cache-demo
├── pom.xml
└── src
    ├── main
    │   ├── java/com/wb/cache
    │   │   ├── CachingApplication.java      # 引导类,加 @EnableCaching
    │   │   ├── domain/User.java             # 实体类,实现 Serializable
    │   │   ├── dao/UserDao.java             # 模拟数据库查询,睡眠 2 秒
    │   │   └── service/UserService.java     # 业务层,缓存注解加在这里
    │   └── resources/application.yml
    └── test/java/com/wb/cache/test
        └── UserServiceTest.java             # 单元测试,循环调用验证

这个场景在交友项目里随处可见:用户资料、视频列表这类读多写少的数据,每次都查库代价太高。

第一步:引入依赖

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

第二步:开启缓存支持

package com.wb.cache;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching  //开启缓存
public class CachingApplication {

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

第三步:@Cacheable 标注查询方法

先看没有缓存时的 Dao 层,用睡眠 2 秒模拟查库耗时:

package com.wb.cache.dao;

import com.wb.cache.domain.User;
import org.springframework.stereotype.Repository;

@Repository
public class UserDao {

    public User findById(Long id) {
        System.out.println("查询数据库");
        try {
            // 睡眠 2 秒,模拟查询数据库的耗时
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new User(id, "张三");
    }

    public void update(Long id) {
        System.out.println("根据id更新");
    }
}

业务层加上 @Cacheable:

package com.wb.cache.service;

import com.wb.cache.dao.UserDao;
import com.wb.cache.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    /**
     * value:缓存名称空间(分组)
     * key:缓存键,支持 SpEL,#id 引用方法参数
     * Redis 下的键命名规则:value + "::" + key
     */
    @Cacheable(value = "user", key = "#id")
    public User findById(Long id) {
        return userDao.findById(id);
    }
}

value 是必填的,它指定了缓存存放在哪个命名空间;key 用 SpEL 表达式引用方法参数,最终 Redis 里的键形如 user::2。同一个 value 下不同 key 互不干扰,不同 value 之间完全隔离。

运行验证

写一个循环调用五次的测试:

package com.wb.cache.test;

import com.wb.cache.domain.User;
import com.wb.cache.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.test.context.junit4.SpringRunner;

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

    @Autowired
    private UserService userService;

    @Test
    public void testFindById() {
        // 循环调用五次,观察耗时与数据库访问次数
        for (int i = 0; i < 5; i++) {
            User user = userService.findById(2L);
            System.out.println(user);
        }
    }
}

先注释掉 @Cacheable 跑一遍做对照:五次调用全部落到数据库,控制台打印五次「查询数据库」,总耗时 10 秒以上。

加回 @Cacheable 再跑:第一次打印「查询数据库」(约 2 秒),后四次没有任何数据库日志,瞬间返回。这就是缓存生效的直接证据。

命中

未命中

调用 findById(2)

缓存 user::2 存在?

直接返回缓存数据
(不执行方法体)

执行方法体
查询数据库(2 秒)

结果写入缓存 user::2

返回结果

后续调用直接命中

想看得更细,可以把日志级别调到 debug 观察 CacheInterceptor 的命中记录:

logging:
  level:
    org.springframework.cache: debug

底层实现切换

入门案例默认跑在 ConcurrentMapCacheManager 上,缓存存在 JVM 内存 Map 里。它有两个致命限制:

对比项ConcurrentMap(默认)Redis
存储位置JVM 内存独立缓存服务
重启后缓存全部丢失数据还在
过期时间不支持 TTL支持
多实例共享不支持(各存各的)支持
适用场景单机演示、开发调试生产环境

好消息是切换成本几乎为零:引入 spring-boot-starter-data-redis 并在 yml 里配上连接,Spring Boot 检测到 Redis 后自动把 CacheManager 换成 RedisCacheManager,业务注解一行不动,这就是开头说的「接口与实现分离」。

spring:
  redis:
    host: 192.168.136.160
    port: 6379
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

按缓存名称空间设置不同 TTL(如视频列表缓存 30 秒)的 RedisCacheManagerBuilderCustomizer 详细配置,属于通用缓存SpringCache:配置视频列表缓存功能的内容,这里只需要知道「换了 Redis 就能配过期时间」。

AOP 代理的原理

@Cacheable 生效的前提是调用方拿到的是 Spring 创建的代理对象:外部注入 UserService 时拿到的其实是缓存的代理子类/包装类,调用 findById 会先经过 CacheInterceptor。推论就是那条经典大坑,同类内部调用不走代理:

@Service
public class UserService {

    public void someMethod() {
        // 内部 this 调用,绕过了代理,@Cacheable 完全失效,方法体照样执行
        this.findById(2L);
    }

    @Cacheable(value = "user", key = "#id")
    public User findById(Long id) { ... }
}

this.findById(2L) 里的 this 是原始对象不是代理,缓存拦截器根本没机会介入。和 @Transactional、@Async 是同一个坑,根源也相同:Spring 只能增强它自己创建的对象,你绕过它 new 出来或 this 调用的,它管不着。解法是把被调方法拆到另一个 Bean,或注入自身的代理。

踩坑速查

坑现象原因与解法
同类自调用注解失效内部调用了带 @Cacheable 的方法,缓存不生效、方法照常执行this 调用不走 AOP 代理。拆分到另一个 Bean,或注入自身代理
@Cacheable 方法返回 null默认 null 也会被缓存(底层存 NullValue 占位对象),下次直接命中 null,数据库永远不再被查加 unless = "#result == null" 让空结果不进缓存
key 冲突 / 漏配不同方法共用同一个 value 却忘了写 key,数据互相覆盖;或两个入口用不同 key 写了同一份数据,出现两份缓存同一命名空间内明确每个方法的 key 规则,坚持 value + key 二元组全局唯一
底层实现未配 Redis演示环境一切正常,上线后重启缓存全丢、多实例数据不一致默认是内存缓存。引入 Redis 依赖 + yml 配置,确认 CacheManager 是 RedisCacheManager
@CachePut 与 @Cacheable 混用想着「先查缓存、没有再放」,两个注解同时加在方法上,结果每次都执行方法@CachePut 总是执行方法。查询用 @Cacheable,写操作同步缓存才用 @CachePut,二选一

常见误解澄清

误解事实
SpringCache 是一个缓存中间件,和 Redis 是竞品它是缓存抽象层,不含任何缓存实现;Redis 是它最常见的底层实现之一
加了 @Cacheable 缓存就自动生效前提是启动类有 @EnableCaching,且方法是通过代理对象调用的
value 只是随便起的名字它决定缓存的命名空间,Redis 下直接参与真实键的构成(value::key),也是 allEntries 清除的范围
@Cacheable 返回 null 会抛异常默认不会抛异常,而是把 null 也缓存起来;要用 unless 显式排除
注解方法内再调用其他缓存方法也走缓存同类内部调用不走代理,不走缓存

官方文档

总结

  • SpringCache 的本质是缓存抽象层 + AOP 声明式缓存:注解声明意图,代理拦截执行,底层实现可替换。
  • 入门三步:spring-boot-starter-cache 依赖、启动类 @EnableCaching、查询方法上 @Cacheable(value = "...", key = "...")。
  • @Cacheable 管读(命中即返回),@CachePut 管写后同步,@CacheEvict 管失效,@Caching 负责组合。
  • 默认的 ConcurrentMap 只适合演示,生产环境引入 Redis 依赖即自动切换到 RedisCacheManager。
  • 自调用失效是所有 AOP 注解的通病,记住「Spring 只增强它创建的对象」。

后续可以顺着这里的工程继续,把 @CachePut、@Caching 等注解逐个跑一遍,对应通用缓存SpringCache:入门案例,之后进入通用缓存SpringCache:常用注解的完整注解详解。

Python爬虫实战:抓取全球各国海关进出口数据的全流程教程 本文系统介绍了用Python采集全球各国海关进出口数据的完整流程,从数据源调研、技术选型,到代码实战、数据处理和存储,最后还拓展了进阶反爬和动态内容处理方法。希望这篇博文能帮助你掌握专业的数据采集技能,为后续数据分析和商业应用奠定坚实基础。 阅读详情

相关推荐

Windows Server安装Intel I219-V网卡驱动完整教程

在Windows Server系统上安装Intel I219-V网卡驱动的方法。

小白成长历程 5172

SpringBoot交友APP项目实战(详细介绍+案例源码) - 9.小视频(SpringCache缓存)

搭建一个Java框架的移动端交友APP,涵盖登录、注册、动态、即时通讯、视频(算法推荐)、个人中心等功能; 技术选型: Spring Boot + SpringMVC + Mybatis + MybatisPlus + Dubbo,即时通讯选用环信即时通讯

yuan 2799

51单片机STC8G1K08驱动ws2812记录

使用51单片机控制17个2812灯,这里选择STC8芯片,最大频率可以达到35M,参考网上的各种文章案例,使用定时器做的时候实测做不到规格书要求的245-345ns,STC8G1K08不带PWM,所以只能使用nop来做,好在单片机在这里只有做编程灯的功能,省略测试过程,下面是程序,使用的是24MHz内部晶振 //设置一个灯珠 void SendOnePix(unsigned char *ptr) { unsigned char i,j; unsigned char temp; fo...

的博客 7320

Java 项目实战: 交友项目 - 小视频模块实战:访客记录、FastDFS 存储与 SpringCache 缓存

本文实现小视频模块核心功能:基于MongoDB记录“谁看过我”访客数据,使用FastDFS分布式文件系统存储视频与缩略图,通过Dubbo服务完成发布与列表接口。结合Spring Cache注解(@Cacheable/@CacheEvict)对视频列表缓存30秒,发布后自动清空缓存,提升性能并保证数据实时性。工程新增视频、访客实体及缓存配置,三条技术线(MongoDB、FastDFS、Redis)协同支撑完整链路。

Wang的专栏 326

DNS入侵检测 datacon2020

DNS入侵检测 datacon2020。

weixin_51491521的博客 523

解析AI人工智能领域AI芯片的散热技术

当你用ChatGPT写代码、用AI生成高清图片时,背后的AI芯片可能正在“发高烧”——全球TOP500超算的平均功耗已突破10兆瓦,单颗GPU的峰值功耗超过700W(相当于3台家用空调同时运行)。本文将聚焦AI芯片的散热技术,覆盖从基础原理到前沿方案的全链条解析,帮助读者理解“散热为什么比算力更重要”。

AIGC应用创新大全的博客 935

Java 项目实战: 交友项目 - 通用缓存SpringCache:问题引入

小视频列表接口高频请求导致频繁穿透Redis、MongoDB与MySQL,造成数据库压力过大。该数据读多写少且可容忍短暂旧数据,适合缓存。通过手写缓存代码发现存在重复逻辑、维护困难、失效机制缺失等问题。引入SpringCache的声明式注解方案,以AOP实现缓存管理,解决“缓存什么、缓存多久、如何失效”三大问题,显著提升性能与可维护性。

Wang的专栏 378

RK3588开发板NPU加速YOLO目标检测完整实战教程

🚀 RK3588开发板NPU加速YOLO目标检测实战 本文详细介绍了如何在瑞芯微RK3588开发板上利用内置NPU加速YOLO目标检测的全流程: 1️⃣ 环境准备:配置RKNPU2 SDK和aarch64交叉编译器,搭建Ubuntu开发环境 2️⃣ 模型转换:从ONNX格式转换为专用RKNN模型,适配NPU硬件特性 3️⃣ 性能对比:NPU推理将处理时间从833ms降至50ms以下,帧率提升16倍 4️⃣ 实战应用:支持图像/视频流/摄像头实时检测,提供完整编译和运行命令 关键优势:专为边缘AI设计的6T

FJN110的博客 931

Java 项目实战:交友项目 - 查询视频列表

小视频列表接口采用“推荐优先、时间兜底”策略:优先从Redis获取用户推荐视频ID串,按页码截取后批量查询MongoDB;若无推荐或已翻完,则按created倒序分页查询全量视频。通过page - redisPages实现页码无缝衔接,确保推荐与兜底区连续。接口返回带作者信息的VideoVo,关注/点赞状态暂置0,后续填充。整体设计兼顾性能与体验,实现高效信息流加载。

Wang的专栏 519

Python爬虫实战:携程/飞猪酒店信息爬取与动态价格分析

在当今数字化旅游时代,酒店预订平台的复杂筛选条件和动态定价机制为数据分析和价格监控带来了巨大挑战。本文将深入探讨如何使用最新的Python爬虫技术来抓取携程和飞猪平台的酒店信息,处理复杂的筛选条件,并解析动态价格数据。本文详细介绍了如何使用最新的Python爬虫技术来抓取携程和飞猪平台的酒店信息。通过结合httpxplaywrightparsel强大的反反爬虫能力:通过浏览器指纹伪装、请求签名、智能延迟等技术应对各种反爬措施高效的数据解析:使用CSS选择器和XPath精确提取所需信息灵活的数据存储。

2201_76125261的博客 414

私家侦探如何追踪难以找到的人,掌握几个很少人知道的在线免费查询网站,搜索人名、电话号码以及地址的开源网站

私家侦探如何追踪难以找到的人,掌握几个很少人知道的在线免费查询网站,搜索人名、电话号码以及地址的开源网站。

代码讲故事 6485

Java 项目实战:交友项目 - SpringCache 入门案例深化:key 写法、RedisCacheManager 与写时失效

本文以交友项目视频列表缓存为例,解答 SpringCache 落地三大核心问题:key 生成防串号(通过 SpEL 组合 userId+page+pagesize)、Redis 过期时间与序列化配置(RedisCacheConfig 按 cacheName 设置 TTL,使用 GenericJackson2JsonRedisSerializer)、数据变更时缓存失效策略(发布视频时用 @CacheEvict(allEntries=true) 清除对应分组)。结合工程实读与踩坑验证,实现精准、可维护的缓存方案

Wang的专栏 733

Android系统解决-授予管理所有文件的权限问题

Android版本一直在加,Android9/Android10/Android11/Android12/Android13/Android14/Android15 , 客户app 也在不断适配,但是存在特别是定制产品中,客户不愿意适配,啥问题都让系统解决,绕过一定机制、实现。这里说的就是一个常见的常见需求:Android13 上面,客户要求默认授予管理所有文件的权限,如下:问题是机器重启后这个权限仍需要重新打开才行,那就是每次开机使用某些功能前都需要授权一次。是的ADB对应命令。

十年饮冰,难凉热血 2539

探花交友_第9章_小视频方案(新版)

探花交友_第9章_小视频方案(新版) 1. 我的访客 1.1 需求分析 1.1.1 功能说明 1.1.2 数据库表 1.2 记录访客数据 tanhua-model tanhua-app-server tanhua-dubbo-interface tanhua-dubbo-mongo 1.3 首页谁看过我 需求分析 tanhua-model tanhua-app-server MovementController MovementService tanhua-dubbo-interface tanhua-du

无 1510

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Camera2Demo

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

基 Spring Boot 2.x 构建的商城系统

阅读文本大概需要3分钟。作者: @城风 来源:https://juejin.im/post/5ca1b08fe51d455201119177本项目是和小伙伴开发的一套基...

天行健,君子以自强不息;地势坤,君子以厚德载物。 204

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

城风——基于SpringBoot2构建社区商城系统开源

本项目是和小伙伴开发的一套基于SpringBoot2的社区商城系统。主要是为了方便用户交友的同时拼单购物。本项目目前还属于雏形,但基本的业务已经实现了大概。基于该系统的前端采用Vue构建。同时兼顾Android和小程序端,前端展示正在开发过程中,后续会展出。 项目地址: github.com/fuyunwang/C… 项目的缘由 在当前互联网飞速发展的大潮下,人们的生活也变的更加便捷。本项目就...

weixin_33747129的博客 907

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 282

Spring AI + GPT-5.5 + Ollama 配置教程:Base URL、超时与流式调用

由于不同 Spring AI、Spring Boot 小版本之间仍可能存在差异,创建项目时应检查 Spring Initializr、Spring AI BOM 和官方兼容矩阵,不要直接复制旧教程中的 Starter 名称和版本号。多人项目最好隔离不同客户端,并在脱敏前提下记录最终 URL、状态码、请求耗时、请求 ID 和模型 ID。Spring AI 接入模型 API,至少要同时确认 Starter、Base URL、请求路径、API Key、模型 ID、连接超时、读取超时和流式客户端这 8 项。

2601_95893075的博客 232

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 346

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 126

Spring Boot 数据源与 MyBatis(-Plus) 自定义配置详解

本文详解 Spring Boot 中单数据源环境下 HikariCP 与 MyBatis-Plus 的自定义配置。通过手动声明 SqlSessionFactory,实现下划线转驼峰、日志输出、一级缓存策略等精细化控制。结合 HikariCP 核心参数调优(如最大连接数、连接生命周期),确保高性能与稳定性。适用于仅需访问单一数据库的场景,避免多数据源复杂性,兼顾性能与可维护性。

BADAO_LIUMANG_QIZHI的博客 196

LeetCode Hot 100 二叉树专题(二)3 题(Java)

本篇文章共 3 题:543. 二叉树的直径、102. 二叉树的层序遍历、108. 将有序数组转换为二叉搜索树。 每道题都统一按「① 题目分析 & 解题思路 → ② 常见解法(附代码)及讲解 → ③ 知识点总结」的顺序组织;代码使用 Java 编写,节点定义沿用 LeetCode 默认的 TreeNode。

2401_88612756的博客 365

Decorator

TaskDecorator 是异步场景下"跨线程传递上下文"的标准方案,主要用于传递 MDC、用户信息、数据源路由等上下文数据,核心价值是让异步任务的日志链路不中断、业务上下文不丢失。TaskDecorator 是 Spring 提供的一个钩子接口,用于在异步任务执行前对 Runnable 进行包装,常用于跨线程传递上下文。如果你在项目中遇到具体的异步上下文传递问题,可以把代码贴出来,我帮你给出最合适的 Decorator 方案 👍。✅ 核心能力:在线程切换时,把"父线程的上下文"搬到"子线程"

wlwork66的博客 106

JDK 下载安装:装完 Java 提示「不是内部或外部命令」?环境变量没配

JDK 是写 Java 程序必须装的东西。它包含运行 Java 的虚拟机(JRE)和编译 Java 的编译器(javac)——装了它,能跑、.java文件能编译成可执行程序。免费,学习和小规模生产都不花钱。

科小怪的博客 630

C++ 多态详解:作用、原理与实战用法

多态是C++面向对象的核心特性,通过虚函数实现运行期动态绑定,使同一接口在不同对象上表现出不同行为。其核心作用包括统一接口、提升可扩展性、降低耦合、支持运行时分派与批量处理。实现依赖虚函数表(vtable)和虚指针(vptr),需注意虚析构函数、对象切片等陷阱。相比编译期多态(模板),运行期多态灵活性高但有调用开销。合理结合两者,可兼顾代码的灵活性与性能,是构建可扩展、低耦合系统的关键。

2402_85743155的博客 382

java框架大全

java框架大全

qq_39326137的博客 183
上一篇: Java 项目实战: 交友项目 - 通用缓存SpringCache:问题引入
下一篇: Java 项目实战:交友项目 - SpringCache 入门案例深化:key 写法、RedisCacheManager 与写时失效
Wang's Blog
博客等级 码龄12年 7418粉丝 2407原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值