目录
- 〇、常用注解
 - 一、@Cacheable注解
 - 1.1 案例
 - 1.2 核心源码
 - 二、@CachePut
 - 2.1 案例
 - 2.2 核心源码
 - 三、@CacheEvict
 - 3.1 案例
 - 3.2 核心源码
 - 四、@Caching(不常用)
 - 4.1 案例
 - 4.2 核心源码
 - 五、@CacheConfig
 - 5.1 案例
 - 5.2 核心源码
 - 六、@EnableCaching
 - 6.1 核心源码
 
〇、常用注解
| 包地址 | 注解名 | 作用域 | 作用 | 
|---|---|---|---|
| org.springframework.cache.annotation | CacheConfig | 类级别 | 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;
}
			
	声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
		
评论(0)