【问题标题】:Spring Caching Implementation in a Java app?Java应用程序中的Spring缓存实现?
【发布时间】:2021-11-08 14:35:47
【问题描述】:

在我基于 Spring Boot 的 Java 应用中,我正在尝试为以下服务方法实现缓存机制:

@Override
public List<EmployeeDTO> findAllByCountry(Country country) {
    final Map<Pair<UUID, String>, List<CountryTranslatable>> valueList 
        = countryRepository...
        // code omitted for brevity
}

在关于这个问题的几个例子之后,我决定采用A Guide To Caching in Spring中提到的方法。

但是,我有点困惑,因为它包含 Spring 和 Spring Boot 实现并使用不同的注释示例。我想我应该从3.1开始。在使用 Spring Boot 时使用 Spring Boot 部分,但我不确定应该使用哪个缓存注释(4.1。@Cacheable 似乎没问题,但我不确定)。

那么,我应该把SimpleCacheCustomizer 放在哪里,如何将这种方法应用于我上面的服务方法(findAllByCountry)?任何简单的例子都会非常感激,因为我是 Spring 的新手。

【问题讨论】:

    标签: java spring spring-boot caching


    【解决方案1】:

    如果您是初学者,则不需要任何自定义,并且只需要基础知识,然后执行以下操作

    @Configuration
    @EnableCaching
    public class CachingConfig {
    
        @Bean
        public CacheManager cacheManager() {
            return new ConcurrentMapCacheManager();
        }
    }
    

    提供的文章指出return new ConcurrentMapCacheManager("addresses");,但您可以使用默认构造函数,稍后将使用@Cacheable("addresses") 创建地址的相关缓存。所以不需要在配置中。

    你还需要

    @Cacheable("employeesList")
    @Override
    public List<EmployeeDTO> findAllByCountry(Country country) {
        final Map<Pair<UUID, String>, List<CountryTranslatable>> valueList 
            = countryRepository...
            // code omitted for brevity
    }
    

    准备好了,这是基本设置

    【讨论】:

    • 非常感谢您的有益回答,投了赞成票。它运行良好,但为什么示例实现不起作用?它 (SimpleCacheCustomizer) 没有 @Configuration@EnableCaching 注释,但可能没有问题,因为它在 Baeldung 上。有什么想法吗?
    • 也许我在 Baeldung 的例子中遗漏了一些要点。您能否看看github.com/eugenp/tutorials/tree/master/spring-caching/src/main/…,让我知道我应该如何将该示例应用到我的项目中?您可以将该实现作为第二种方法添加到您的答案中。
    • 是的,我知道,这就是我感到困惑的原因。但由于我可能需要进一步的实现,如果您发布该示例的必要部分(有一个配置等我没有使用),我将不胜感激
    • 非常感谢朋友,我意识到我错过了 CachingConfig 部分的CachingConfig 实现。实施后,现在它正在工作。但我不在ConcurrentMapCacheManager 中使用“地址”。我觉得还可以吧?
    • 那么,我们可以说我可以在以下字段中使用相关名称吗? cacheManager.setCacheNames(asList("users"));@Cacheable("users").
    【解决方案2】:

    如果你想自定义自动配置的缓存管理器,那么只有你应该实现 CacheManagerCustomizer 接口。

    在通常情况下,您不需要自定义自动配置的缓存管理器。该示例已在您附加的链接中给出。

    您对可缓存注释的理解也是正确的,它应该适合您。

    您可以将该组件类与其他类放在组件扫描范围内。

    【讨论】:

      【解决方案3】:

      你应该把你的SimpleCacheCustomizer 和你的其他Spring 配置类放在一起。这样,Spring 将扫描和加载您的组件。

      @Component
      public class SimpleCacheCustomizer 
        implements CacheManagerCustomizer<ConcurrentMapCacheManager> {
      
          @Override
          public void customize(ConcurrentMapCacheManager cacheManager) {
              cacheManager.setCacheNames(asList("employeesList", "otherCacheName"));
          }
      }
      

      要将缓存与您的服务一起使用,请添加注释@Cacheable("employeesList")

      @Cacheable("employeesList")
      @Override
      public List<EmployeeDTO> findAllByCountry(Country country) {
          final Map<Pair<UUID, String>, List<CountryTranslatable>> valueList 
              = countryRepository...
              // code omitted for brevity
      }
      

      如果您想验证缓存是否正常工作,只需在您的Spring 配置中启用sql_query 并检查findAllByCountry 是否不再向数据库发出任何请求。

      【讨论】:

      • 1. 非常感谢您的示例。我认为employeesList 是一个自定义名称,在SimpleCacheCustomizerfindAllByCountry 方法的@Cacheable 注释中应该相同。这是真的吗?
      • 2. 我想我会在cacheManager.setCacheNames(asList()) 中添加其他缓存字段,例如otherCacheName。这是真的吗?
      • 对于 1. 是的,你是对的,employeesList 只是缓存的名称。您可以设置任何您想要的内容,但您的 SimpleCacheCustomizer 必须与 @Cacheable 注释中的相同。 2. 是的,这只是一个示例,向您表明您可以在此处设置要使用的其他缓存名称。
      • 我尝试了这种方法,但不幸的是,每个请求都会进入 db。我尝试在我的服务接口上使用@Cacheable 注释,但它不起作用。然后我也在 ServiceImpl 类上试过了,但还是一样。知道我错过了什么吗?
      • 你的组件SimpleCacheCustomizer是由Spring加载的吗?
      猜你喜欢
      • 1970-01-01
      • 2016-09-13
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 2013-03-21
      • 2012-01-04
      • 2023-03-03
      • 2014-07-16
      相关资源
      最近更新 更多