SpringBoot @Cacheable缓存注解的使用

1. 引入缓存依赖

		<!---->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        
        <!--这边用的是Redis缓存,所以加上这个依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2. application.properties 配置

spring:
  cache:
    type: redis
  redis:
    database: 5
    host: 192.168.25.129
    port: 6379
    password: 123456

3. 准备基本的Controller、Service代码

public interface RedisService {
    String getString(String name);
}
@Service
public class RedisServiceImpl implements RedisService {
    @Override
    public String getString(String name) {
        return "hello " + name;
    }
}
@RestController
@RequestMapping("/redis")
public class RedisController {

    @Autowired
    private RedisService redisService;

    @RequestMapping("/getString1")
    public String getString1(@RequestParam String name){
        return redisService.getString(name);
    }
}

4. @Cacheable注解

4.1 cacheNames和value

指定缓存的名字,可以通过数组的方式指定多个缓存。

    @AliasFor("cacheNames")
    String[] value() default {};

    @AliasFor("value")
    String[] cacheNames() default {};

修改前面的代码,在ServiceImpl的方法上,加上@Cacheable注解并指定value属性

    @Override
    @Cacheable(value = {"REDIS:GETSTRING1"})
    public String getString(String name) {
        return "hello " + name;
    }

运行SpringBoot程序,在浏览器输入 http://localhost:99/redis/getString1?name=fuhb,然后查看Redis缓存确认是否生成对应的key

127.0.0.1:6379[5]> KEYS *
1) "REDIS:GETSTRING1::fuhb"

由此可见,默认会以 value + 参数的格式生成 Redis Key。

如果是多个参数的情况下,Redis Key会是什么格式呢?

    @RequestMapping("/getString2")
    public String getString2(@RequestParam String name){
        return redisService.getString(name, "test");
    }
    @Override
    @Cacheable(value = {"REDIS:GETSTRING2"})
    public String getString(String name, String tag) {
        return tag + " " + name;
    }

同样的,在浏览器输入 http://localhost:99/redis/getString2?name=fuhb,再查看Redis Key信息

127.0.0.1:6379[5]> KEYS *
1) "REDIS:GETSTRING2::SimpleKey [fuhb,test]"
2) "REDIS:GETSTRING1::fuhb"

由此可见,参数以 SimpleKey [参数拼接] 的格式进行组合。所以,接下来讲一下 key 和 keyGenerator 属性的使用

4.2 key 和 keyGenerator

keyGenerator

SpringBoot默认使用的是SimpleKeyGenerator生成key,其生成规则如下:

  • 当参数为空时,返回空
  • 当参数只有一个时,返回第一个参数的值
  • 当参数大于一个时,返回SimpleKey对象,其序列化格式上面讲过了,代码比较简单
    public String toString() {
        return this.getClass().getSimpleName() + " [" + StringUtils.arrayToCommaDelimitedString(this.params) + "]";
    }

如果需要自定义KeyGenerator,可以参考这篇文章:@Cacheable自定义KeyGenerator

key

相较于keyGenerator,官方更推荐直接显示地指定key

    @Override
    @Cacheable(value = {"REDIS:GETSTRING3"}, key = "#tag + #name")
    public String getString4(String tag, String name) {
        return tag + " " + name;
    }

或者用这种写法,p0、p1来替代参数名

    @Override
    @Cacheable(value = {"REDIS:GETSTRING4"}, key = "#p0 + #p1")
    public String getString4(String tag, String name) {
        return tag + " " + name;
    }

key 和 keyGenerator 参数是互斥的,不能同时使用

4.3 cacheManager 和 cacheResolver

CacheManager,缓存管理器是用来管理(检索)一类缓存的。通常来讲,缓存管理器是与缓存组件类型相关联的。我们知道,spring 缓存抽象的目的是为使用不同缓存组件类型提供统一的访问接口,以向开发者屏蔽各种缓存组件的差异性。那么 CacheManager 就是承担了这种屏蔽的功能。spring 为其支持的每一种缓存的组件类型提供了一个默认的 manager,如:RedisCacheManager 管理 redis 相关的缓存的检索、EhCacheManager 管理 ehCache 相关的缓等。

CacheResolver,缓存解析器是用来管理缓存管理器的,CacheResolver 保持一个 cacheManager 的引用,并通过它来检索缓存。CacheResolver 与 CacheManager 的关系有点类似于 KeyGenerator 跟 key。spring 默认提供了一个 SimpleCacheResolver,开发者可以自定义并通过 @Bean 来注入自定义的解析器,以实现更灵活的检索。

大多数情况下,我们的系统只会配置一种缓存,所以我们并不需要显式指定 cacheManager 或者 cacheResolver。但是 spring 允许我们的系统同时配置多种缓存组件,这种情况下,我们需要指定。指定的方式是使用 @Cacheable 的 cacheManager 或者 cacheResolver 参数。

4.4 sync

sync=true表示同步,也就是缓存的入口将被锁住,直到上一个线程的操作完成,可以避免缓存击穿的问题。默认情况是false,也就是异步访问,初始状态下缓存不存在,如果有大量的线程同时访问,会因为没有缓存而对DB造成较大压力。

4.5 condition

缓存的条件,只有当condition返回结果为true才使用缓存。该配置支持SpEL表达式,也可以使用result表示取返回值

如下例子,只有当name的值等于admin时,才会构造并使用缓存

    @Override
    @Cacheable(value = {"REDIS:GETSTRING5"}, key = "#p0 + #p1", condition = "#name == 'admin'")
    public String getString5(String tag, String name) {
        return tag + " " + name;
    }

4.6 unless

不使用缓存的条件,跟上面的condition相反

如下例子,当name的值等于admin时不使用缓存

    @Override
    @Cacheable(value = {"REDIS:GETSTRING6"}, key = "#p0 + #p1", unless = "#name == 'admin'")
    public String getString6(String tag, String name) {
        return tag + " " + name;
    }
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
@Cacheable注解Spring框架中用于缓存方法返回结果的注解。当一个方法被@Cacheable注解标记后,Spring会检查缓存中是否存在该方法的返回值,如果存在,则直接从缓存中获取结果并返回;如果不存在,则执行方法体,并将返回值存入缓存中。 使用@Cacheable注解需要注意以下几点: 1. 在需要缓存结果的方法上使用@Cacheable注解。 2. 可以指定缓存的名称,通过value属性来指定,如:@Cacheable(value="myCache")。 3. 可以指定缓存的Key,通过key属性来指定,如:@Cacheable(key="#param")。其中#param表示方法的参数值,还可以使用SpEL表达式来动态构建key。 4. 默认情况下,缓存的Key是由方法的所有参数组成的,如果不希望使用所有参数构建Key,可以使用condition属性来限制条件,如:@Cacheable(condition="#param.length() < 10")。这里的condition表示只有当参数长度小于10时才进行缓存。 5. 可以指定缓存的过期时间,通过设置expire属性来指定,如:@Cacheable(expire=3600)。单位为秒,默认为-1,表示永不过期。 示例代码: ```java @Service public class UserService { @Cacheable(value = "users", key = "#id") public User getUserById(String id) { // 从数据库中获取用户信息 // ... return user; } } ``` 上述示例中,getUserById方法会根据id参数从缓存中获取User对象,如果缓存中不存在,则执行方法体并将返回值存入缓存。 需要注意的是,@Cacheable注解只能用于Spring容器管理的Bean中,即被@Service、@Component等注解标记的类中的方法才能被缓存。另外,为了使@Cacheable注解生效,需要在Spring配置文件中配置缓存管理器(如使用EhcacheRedis等)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

°Fuhb

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

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

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

打赏作者

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

抵扣说明:

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

余额充值