SpringCache源码解析Annotation案例讲解

 更新时间:2024年08月29日 09:51:11   作者:钱多多_qdd  
这篇文章主要介绍了SpringCache源码解析Annotation的相关知识,本文通过案例讲解的非常详细,感兴趣的朋友跟随小编一起看看吧

〇、常用注解

包地址注解名作用域作用
org.springframework.cache.annotationCacheConfig类级别s设置缓存的公共配置
Cacheable方法级别缓存读取操作
CacheEvict方法级别缓存失效操作
CachePut方法级别缓存更新操作
Caching方法级别h混合读取、失效、更新操作
CacheConfig方法级别统一配置缓存注解的属性,作用于类
EnableCaching方法级别开启缓存功能

一、@Cacheable注解

属性默认值描述
value缓存的名称,在 spring 配置文件中定义,必须指定至少一个
cacheNames缓存的名称,在 spring 配置文件中定义,必须指定至少一个
key缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
keyGenerator
cacheManager
cacheResolver
condition缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存。不能使用返回结果
unless不缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 false才进行缓存。可以使用返回结果
sync
  • 简介:表示该方法执行后的结果可以被缓存;可作用于类和方法,作用于类上,则表示对该类的所有方法都有效;
  • 执行逻辑:查找对应的缓存是否存在,若不存在,该方法会被调用,并且将返回结果放入缓存;若存在,则不调用方法,直接返回缓存的结果;

1.1 案例

注解业务案例 单一缓存名称和键:

@Cacheable("books")
public Book findBookById(String id) {
    // 业务逻辑
}

多个缓存名称和条件:

@Cacheable(value = {"books", "archivedBooks"}, condition = "#id.length() > 10")
public Book findBookWithComplexKey(String id) {
    // 业务逻辑
}
@Service
public class MyService {
    /**
     * 一个使用 @Cacheable 所有属性的案例。
     * 
     * @param id 用户ID
     * @return 返回用户对象
     */
    @Cacheable(
        value = "users",          // 缓存名称
        key = "#id",              // 缓存键,使用SpEL表达式
        condition = "#id.length() > 3",  // 缓存条件,只有当ID长度大于3时才缓存
        unless = "#result == null" // 除非条件,如果结果为null,则不缓存
    )
    public User findUserById(String id) {
        // 模拟数据库查询操作,这里假设ID长度小于3时没有结果
        if (id == null || id.length() <= 3) {
            return null;
        }
        return performDatabaseQuery(id);
    }
    private User performDatabaseQuery(String id) {
        // 模拟数据库查询逻辑
        return new User(id, "Name based on ID");
    }
}

1.2 核心源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {
    // 缓存KEY所在缓存的标识符,支持多个,CSV格式
    @AliasFor("cacheNames")
    String[] value() default {};
    // 缓存KEY所在缓存的标识符,支持多个,CSV格式
    @AliasFor("value")
    String[] cacheNames() default {};
    // 缓存的KEY,支持SpEL表达式动态计算
    // 默认为空(缺省按照方法的所有参数组合生成SimpleKey)
    String key() default "";
    // 缓存KEY生成器
    String keyGenerator() default "";
    // 缓存管理器
    String cacheManager() default "";
    // 缓存解析器
    String cacheResolver() default "";
    // 缓存的条件,使用SpEL表达式,方法调用前计算,当结果为true时执行动作
    // 默认为空,表示总是缓存方法返回值
    String condition() default "";
    // 否决缓存的条件,使用SpEL表达式,方法调用后计算(可使用result),当结果为true时不执行动作
    // 默认为空,表示永不否决;
    String unless() default "";
    // 使用异步模式标识
    boolean sync() default false;
}

二、@CachePut

注解作用:@CachePut 注解用于在方法执行后更新缓存。
注解属性:与@Cacheable相同。

  • 简介:表示该方法执行后的结果需要更新到缓存;可作用于类和方法,作用于类上,则表示对该类的所有方法都有效;
  • 执行逻辑:和Cacheable不同的是,带有CachePut注解的方法一定会被执行,方法执行后的结果由condition/unless判定是否存入缓存;

2.1 案例

@CachePut("books")
public Book updateBookDetails(String id, Book details) {
    // 业务逻辑
}
@Service
public class MyService {
    /**
     * 使用 @CachePut 所有属性的案例。
     *
     * @param user 用户对象,包含ID
     * @return 更新后的用户对象
     */
    @CachePut(
        value = "users",      // 缓存名称
        key = "#user.id",     // 缓存键,使用SpEL表达式
        condition = "#user.age > 18"  // 条件,只有当用户年龄大于18时才更新缓存
    )
    public User updateUserProfile(User user) {
        // 模拟更新用户信息的业务逻辑
        return performUpdate(user);
    }
    private User performUpdate(User user) {
        // 模拟更新逻辑
        user.setName("Updated Name");
        return user;
    }
}

2.2 核心源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CachePut {
    // 缓存KEY所在缓存的标识符,支持多个,CSV格式
    @AliasFor("cacheNames")
    String[] value() default {};
    // 缓存KEY所在缓存的标识符,支持多个,CSV格式
    @AliasFor("value")
    String[] cacheNames() default {};
    // 缓存的KEY,可以为空(缺省按照方法的所有参数组合生成SimpleKey);
    // 支持SpEL表达式
    String key() default "";
    // KEY的生成器
    String keyGenerator() default "";
    // 缓存管理器
    String cacheManager() default "";
    // 缓存解析器
    String cacheResolver() default "";
    // 放置缓存的条件,使用SpEL表达式,方法调用后计算(可使用result),当结果为true时执行动作
    // 默认为空,表示方法结果总是被缓存
    String condition() default "";
    // 否决放置缓存的条件,使用SpEL表达式,方法调用后计算(可使用result),当结果为true时不执行动作
    // 默认为空,表示永不否决;
    String unless() default "";
}

三、@CacheEvict

注解作用:@CacheEvict 注解用于在方法执行后清除缓存。

注解属性介绍

  • value 或 cacheNames: 指定缓存名称,可以是单个或多个;
  • allEntries: 清除所有缓存项;
  • condition: 指定清除缓存的条件SpEL表达式;

简介:表示清除该方法的缓存KEY对应的缓存;可作用于类和方法,作用于类上,则表示对该类的所有方法都有效;

3.1 案例

清除特定缓存名称的条目:

@CacheEvict("books")
public void deleteBook(String id) {
    // 业务逻辑
}

清除所有缓存名称的所有条目:

@CacheEvict(allEntries = true)
public void clearAllCaches() {
    // 业务逻辑
}

3.2 核心源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheEvict {
    // 缓存KEY所在缓存的标识符,支持多个,CSV格式
    @AliasFor("cacheNames")
    String[] value() default {};
    // 缓存KEY所在缓存的标识符,支持多个,CSV格式
    @AliasFor("value")
    String[] cacheNames() default {};
    // 缓存的KEY,可以为空(缺省按照方法的所有参数组合生成SimpleKey);
    // 支持SpEL表达式
    String key() default "";
    // KEY的生成器
    String keyGenerator() default "";
    // 缓存管理器
    String cacheManager() default "";
    // 缓存解析器
    String cacheResolver() default "";
    // 清除缓存的条件,使用SpEL表达式,执行次序由beforeInvocation()决定
    // 默认为空,表示总是清除缓存
    String condition() default "";
    // 删除缓存中所有条目标识
    // 默认为false,表示只删除指定KEY的值
    boolean allEntries() default false;
    // 方法调用前执行标识
    // 默认为false,表示方法成功调用(未抛出异常)后执行;为true则方法调用前执行
    boolean beforeInvocation() default false;
}

四、@Caching(不常用)

注解作用:@Caching 注解用于组合多个缓存操作。

注解属性介绍

  • value: 包含多个缓存操作的数组;
  • 简介:表示多个Cache注解的组注解;可作用于类和方法,作用于类上,则表示对该类的所有方法都有效;

4.1 案例

@Caching(
    cacheable = {@Cacheable("books")},
    put = {@CachePut("books")},
    evict = {@CacheEvict("archivedBooks")}
)
public Book processBook(String id, Book details) {
    // 业务逻辑
}

4.2 核心源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Caching {
    // Cacheable集合
     Cacheable[] cacheable() default {};
    // CachePut集合
     CachePut[] put() default {};
    // CacheEvict集合
     CacheEvict[] evict() default {};
}

五、@CacheConfig

注解作用:@CacheConfig 注解用于在类级别提供缓存相关的共享配置。

注解属性介绍

  • cacheNames: 指定类中所有缓存操作的默认缓存名称;
  • keyGenerator: 指定默认的缓存键生成器;
  • condition: 指定类中所有缓存操作的默认条件;
  • 简介:提供在类层次上共享缓存相关配置的机制;只可作用于类上;

当作用在某个类上,会给这个类中定义的所有缓存动作提供默认配置,当然,具体缓存动作的配置可覆盖提供的默认配置;

5.1 案例

@CacheConfig(cacheNames = "books", keyGenerator = "customKeyGenerator")
public class BookService {
    // 类中的方法可以使用缓存注解
}

5.2 核心源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CacheConfig {
    // 缓存KEY所在缓存的标识符,支持多个,CSV格式
    String[] cacheNames() default {};
    // KEY的生成器
    String keyGenerator() default "";
    // 缓存管理器
    String cacheManager() default "";
    // 缓存解析器
    String cacheResolver() default "";
}

六、@EnableCaching

简介:
表示启用Spring的注解驱动的缓存管理能力,和@Configuration配合使用;

必须创建CacheManager Bean,Spring框架不会提供默认值;@EnableCaching会根据类型搜索CacheManager Bean,因此CacheManager Bean的命名并不重要;
可以实现CachingConfigurer接口的cacheManager()方法来创建@EnableCaching指定的CacheManager Bean,这种情况下需要明确提供KeyGenerator(@EnableCaching会默认提供SimpleKeyGenerator);如果不需要自定义,可以考虑从CachingConfigurerSupport扩展,它为所有方法提供了默认实现;

6.1 核心源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CachingConfigurationSelector.class)
public @interface EnableCaching {
    // 代理模式:CGLIB or JDK Interface
    // 默认为false,表示基于JDK Interface
    // 设置为true,会影响所有需要代理的Spring管理的Bean
    boolean proxyTargetClass() default false;
    // 缓存应用模式:Proxy or AspectJ
    // Proxy模式只允许通过代理拦截调用,不会拦截同一类中的本地调用
    // AspectJ模式下,proxyTargetClass()无效,会拦截同一类中的本地调用
    AdviceMode mode() default AdviceMode.PROXY;
    // 特定连接点应用多个建议时,缓存操作的执行顺序
    int order() default Ordered.LOWEST_PRECEDENCE;
}

到此这篇关于SpringCache源码解析Annotation案例讲解的文章就介绍到这了,更多相关SpringCache Annotation内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JAVA中堆、栈,静态方法和非静态方法的速度问题

    JAVA中堆、栈,静态方法和非静态方法的速度问题

    这篇文章主要介绍了JAVA中堆、栈,静态方法和非静态方法的速度问题,堆和栈得速度性能分析多角度给大家分析,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-08-08
  • Java MyBatis之Mapper代理详解

    Java MyBatis之Mapper代理详解

    这篇文章主要介绍了Java web中MyBatis的mapper代理,文中有详细的代码示例,具有一定的参考价值,感兴趣的小伙伴可以参考一下
    2023-04-04
  • Maven项目启动报错error in opening zip file的解决方案

    Maven项目启动报错error in opening zip file的解决方

    这篇文章主要介绍了Maven项目启动时常见的`errorinopeningzipfile`错误,分析了其根本原因在于JAR文件损坏,文章提供了多种解决方法,包括删除损坏的JAR文件、清理本地仓库、检查磁盘错误、手动下载等,需要的朋友可以参考下
    2025-10-10
  • 使用React和Java实现文本摘要小工具

    使用React和Java实现文本摘要小工具

    本文将详细介绍如何使用 React 和 Java 搭建一个小型文本摘要工具,并基于 Hugging Face 提供的 API 来实现智能摘要功能,感兴趣的可以了解下
    2024-11-11
  • 在Mac OS上安装Tomcat服务器的教程

    在Mac OS上安装Tomcat服务器的教程

    这篇文章主要介绍了在Mac OS上安装Tomcat服务器的教程,方便进行工作环境下的Java web开发,需要的朋友可以参考下
    2015-11-11
  • Java发起http请求的完整步骤记录

    Java发起http请求的完整步骤记录

    这篇文章主要给大家介绍了关于Java发起http请求的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • Spring事务隔离级别简介及实例解析

    Spring事务隔离级别简介及实例解析

    这篇文章主要介绍了Spring事务隔离级别简介及实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • nacos实现配置多个配置文件(共享配置)

    nacos实现配置多个配置文件(共享配置)

    文章介绍了在Spring Cloud Nacos中配置共享配置文件和扩展配置文件的方法,包括使用`shared-configs`和`extension-configs`属性,并详细解释了这些属性的使用方式和区别,文章还提到旧版本的配置方式已经被弃用,建议使用新的配置方式
    2026-03-03
  • 使用hibernate和struts2实现分页功能的示例

    使用hibernate和struts2实现分页功能的示例

    本篇文章主要介绍了使用hibernate和struts2实现分页功能,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • java对象类型转换和多态性(实例讲解)

    java对象类型转换和多态性(实例讲解)

    下面小编就为大家带来一篇java对象类型转换和多态性(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10

最新评论