当前位置:   article > 正文

Spring Cache(边路缓存)

spring cache

一、Spring Cache介绍

Spring Cache 是Spring - context-xxx.jar中提供的功能,可以结合EHCache,Redis等缓存工具使用。给用户提供非常方便的缓存处理,缓存基本判断等操作,可以直接使用注解实现。 ​ 在包含了Spring - context-xxx.jar的Spring Boot项目中,在启动类中添加@EnableCaching注解,即可开启缓存功能。默认Spring Cache是不开启。

二、Spring Cache加载缓存工具顺序

只要检测到项目中配置了下面缓存工具(导入了依赖,在Spring容器中发现对应工具的内容),无论导入多少个缓存工具依赖,只用优先级最高的一个。 ​ 默认寻找缓存工具的顺序:(为什么Redis配置上就可以用的原因)

  1. Generic

  2. JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)

  3. EhCache 2.x

  4. Hazelcast

  5. Infinispan

  6. Couchbase

  7. Redis

  8. Caffeine

  9. Simple

三、基于Spring Cache完成缓存管理

(1)导入依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.12.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
</dependencies>

(2)编写配置文件

spring:
  redis:
    host: 192.168.8.128
    port: 6379 # 默认值,可省略

(3)编写启动类

@SpringBootApplication
@EnableCaching
public class SpringCacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class,args);
    }
}

四、使用

(1)Cacheable:查询缓存的注解

  1. @Service
  2. public class SpringCacheServiceImpl implements SpringCacheService {
  3. /**
  4. * 查询数据
  5. * Cacheable - 查询缓存的注解。
  6. * 固定流程:
  7. * 1. 根据key访问缓存服务器,查询缓存数据。
  8. * 2. 判断缓存查询结果
  9. * 2.1 缓存查询有结果,直接返回。当前方法不执行
  10. * 2.2 缓存查询无结果,进入后续流程。
  11. * 3. 执行当前方法代码逻辑。
  12. * 4. 代码返回值作为value,保存到缓存服务器中。
  13. * 5. 返回方法的返回结果。
  14. * 属性:
  15. * 完整的缓存key是: cacheNames + "::" + key
  16. * cacheNames - 缓存key的前缀,字符串类型。只能使用字符串字面值赋值。
  17. * key - 缓存key的后缀。字符串类型。可以使用字符串字面值和SpringEL表达式赋值。
  18. * 赋值的时候,如果是字符串的字面值,必须使用 '' 标记。
  19. * @return
  20. */
  21. @Override
  22. @Cacheable(cacheNames = "test", key = "'getAll'")
  23. public List<String> getAll() {
  24. // 模拟数据库访问
  25. System.out.println("开始访问数据库。。。。");
  26. List<String> result = new ArrayList<>();
  27. for(int i = 0; i < 5; i++){
  28. result.add("user-" + i);
  29. }
  30. System.out.println("数据库查询结束,查询结果是:" + result);
  31. return result;
  32. }
  33. }
  1. /**
  2. * 主键查询
  3. * 缓存的key必须和方法参数的值相关。
  4. *
  5. * 使用SpringEL,访问方法的参数表。
  6. * 访问方式有:
  7. * #root.method.args[下标]
  8. * #方法参数变量名
  9. *
  10. * 常见的key属性赋值方式是: 方法名称(参数值)
  11. */
  12. @Override
  13. @Cacheable(cacheNames = "test", key = "#root.methodName + '(' + #id + ')'")
  14. public String getById(Long id) {
  15. System.out.println("开始访问数据库....");
  16. String result = "getById - " + id;
  17. System.out.println("访问数据库结束,查询结果是:" + result);
  18. return result;
  19. }

(2)CachePut: 保存数据到缓存服务器。

  1. /**
  2. * 新增
  3. * 希望保存数据成功后,同时缓存到Redis中。
  4. * 后续主键查询的时候,可以减少数据库查询次数。
  5. *
  6. * CachePut - 保存数据到缓存服务器。是针对新增和更新使用的缓存注解。
  7. * 固定流程:
  8. * 1. 执行当前方法。
  9. * 2. 根据注解拼接key,把方法的返回值作为value,保存的缓存服务器。
  10. * 3. 方法返回
  11. * @return
  12. */
  13. @Override
  14. @CachePut(cacheNames = "test", key = "'getById(' + #id + ')'")
  15. public String add(Long id, String name) {
  16. // 完整的数据
  17. String data = name + " - " + id;
  18. // 保存到数据库
  19. System.out.println("保存数据 【" + data + "】 到数据库");
  20. return data;
  21. }

(3)CacheEvict:缓存淘汰。

  1. /**
  2. * 根据主键删除数据
  3. * 当删除数据库数据成功后,也要删除缓存中的数据。避免查询的时候,基于缓存,
  4. * 查询到脏数据。
  5. *
  6. * CacheEvict - 缓存淘汰。
  7. * 固定流程:
  8. * 1. 执行方法
  9. * 2. 根据注解中的key,访问缓存服务器,删除键值对
  10. * 3. 方法返回。
  11. *
  12. * 属性:
  13. * allEntries - 布尔类型。是否删除cacheNames作为前缀的所有键值对。默认false。
  14. * 谨慎使用。
  15. */
  16. @Override
  17. @CacheEvict(cacheNames = "test", key = "'getById(' + #id + ')'")
  18. public String removeById(Long id) {
  19. System.out.println("删除数据,主键是:" + id);
  20. return "删除主键是" + id + "数据";
  21. }

(4)CachConfig:公共前缀,使用在类上

@CachConfig(cacheNames = "test")

五、condition和unless属性

(1) condition

condition是普通条件。如果条件成立则进行缓存。此判断为进入到方法体之前的判断,所以#result不允许用在这里。如果在condition中出现#result会导致条件恒不成立,不进行缓存。

  1. @Override
  2. @Cacheable(/*cacheNames = "test", */key = "#root.methodName + '(' + #id + ')'",
  3. condition = "#id >= 10"
  4. )
  5. public String getById(Long id) {
  6. System.out.println("开始访问数据库....");
  7. String result = "getById - " + id;
  8. System.out.println("访问数据库结束,查询结果是:" + result);
  9. return result;
  10. }

(2)unless

unless是方法执行完成后的条件,当符合条件不被缓存。注意:#result只能写在这个属性中。多用在返回结果为null时不缓存效果。

  1. @Override
  2. @Cacheable(/*cacheNames = "test", */key = "#root.methodName + '(' + #id + ')'",
  3. unless = "#id >= 10"
  4. )
  5. public String getById(Long id) {
  6. System.out.println("开始访问数据库....");
  7. String result = "getById - " + id;
  8. System.out.println("访问数据库结束,查询结果是:" + result);
  9. return result;
  10. }

(3)SpringEL中的常见变量

 六、Spring Cache缓存管理器配置

  1. @Configuration
  2. public class MySpringCacheConfiguration {
  3. /**
  4. * 创建一个CacheManager,缓存管理器。
  5. * 实现缓存的访问配置管理。
  6. * 如:缓存有效期。键值对的序列化方式等。
  7. * 在SpringCache技术中,要求,一个Spring容器上下文只有唯一的CacheManager对象。
  8. *
  9. * RedisCacheManager - Redis缓存服务器的管理工具。
  10. */
  11. @Bean
  12. public CacheManager cacheManager(RedisConnectionFactory factory){
  13. // 创建默认的缓存配置管理。
  14. RedisCacheConfiguration configuration =
  15. RedisCacheConfiguration.defaultCacheConfig();
  16. // 配置,可以提供缓存有效期和键值对序列化器等。
  17. // RedisCacheConfiguration设计比较特殊。每个配置的修改,都会创建一个新的RedisCacheConfiguration对象并返回。
  18. configuration =
  19. configuration
  20. .serializeKeysWith(
  21. RedisSerializationContext.SerializationPair.fromSerializer(
  22. new StringRedisSerializer()
  23. )
  24. ) // 设置key的序列化工具
  25. .serializeValuesWith(
  26. RedisSerializationContext.SerializationPair.fromSerializer(
  27. new GenericJackson2JsonRedisSerializer()
  28. )
  29. ) // 设置value的序列化工具
  30. .entryTtl(Duration.ofMinutes(30L)) // 设置所有键值对的有效期
  31. .disableCachingNullValues() ; // 是否忽略value为null的数据缓存保存过程。
  32. // 使用构建器,默认构建的管理器,是默认配置逻辑。
  33. // 永久保存数据,key是字符串序列化工具。value是JDKSerializable序列化工具
  34. // 可以提供自定义的配置逻辑。 RedisCacheConfiguration
  35. RedisCacheManager redisCacheManager =
  36. RedisCacheManager
  37. .builder() // 构建器。用于构建RedisCacheManager的工具。必须提供连接工厂
  38. .cacheWriter( // 提供连接工厂
  39. RedisCacheWriter.lockingRedisCacheWriter(factory)
  40. )
  41. .cacheDefaults(configuration) // 基于提供的配置,创建管理器。
  42. .build();
  43. return redisCacheManager;
  44. }
  45. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/929765
推荐阅读
相关标签
  

闽ICP备14008679号