Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么Spring对@Cacheable注释方法的一次调用执行@Cacheable keyGenerator两次_Java_Spring_Spring Boot - Fatal编程技术网

Java 为什么Spring对@Cacheable注释方法的一次调用执行@Cacheable keyGenerator两次

Java 为什么Spring对@Cacheable注释方法的一次调用执行@Cacheable keyGenerator两次,java,spring,spring-boot,Java,Spring,Spring Boot,为什么Spring在一次调用带注释的@Cacheable方法时会执行我的自定义@Cacheable键生成器两次,为什么不执行一次呢 我的密钥生成器实现 package com.example.demo; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.stereotype.Component; import java.lang.reflect.Method; impor

为什么Spring在一次调用带注释的@Cacheable方法时会执行我的自定义@Cacheable键生成器两次,为什么不执行一次呢

我的密钥生成器实现

package com.example.demo;

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * Custom key generator
 */
@Component(value = "customerKeyGenerator")
public class CustomerKeyGen implements KeyGenerator
{
    @Override
    public Object generate(Object target, Method method, Object... params)
    {
        System.out.println("Generating a key");
        ArrayList<String> customerNames = (ArrayList<String>) params[0];
        return customerNames.hashCode();
    }
}
curl http://127.0.0.1:8080/countCustomers
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    18  100    18    0     0     18      0  0:00:01 --:--:--  0:00:01    
76countOfCustomers=2
日志 我在应用程序属性中有以下设置来启用缓存跟踪

logging.level.org.springframework.cache=TRACE

...
2018-08-27 11:56:53.753  INFO 18756 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2018-08-27 11:56:53.757  INFO 18756 --- [           main] c.example.demo.TestCacheableApplication  : Started TestCacheableApplication in 3.543 seconds (JVM running for 5.137)
2018-08-27 11:56:58.411  INFO 18756 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-08-27 11:56:58.411  INFO 18756 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2018-08-27 11:56:58.446  INFO 18756 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 35 ms
Generating a key
2018-08-27 11:56:58.480 TRACE 18756 --- [nio-8080-exec-1] o.s.cache.interceptor.CacheInterceptor   : Computed cache key '104328221' for operation Builder[public int com.example.demo.CustomerService.getCountOfCustomers(java.util.ArrayList)] caches=[customersCache] | key='' | keyGenerator='customerKeyGenerator' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
2018-08-27 11:56:58.480 TRACE 18756 --- [nio-8080-exec-1] o.s.cache.interceptor.CacheInterceptor   : No cache entry for key '104328221' in cache(s) [customersCache]
Generating a key
2018-08-27 11:56:58.480 TRACE 18756 --- [nio-8080-exec-1] o.s.cache.interceptor.CacheInterceptor   : Computed cache key '104328221' for operation Builder[public int com.example.demo.CustomerService.getCountOfCustomers(java.util.ArrayList)] caches=[customersCache] | key='' | keyGenerator='customerKeyGenerator' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
从概念上讲,我认为Spring只需要运行一次keyGenerator,首先使用它查找缓存,如果找不到,当方法完成时,使用相同的键放入缓存。所以我不明白为什么我两次看到这个

我的问题是:

  • 我对它的工作原理和原因感到困惑
  • 日志记录和调试变得混乱
  • 潜在的性能影响,即使keyGeneration实现应该很便宜,为什么要多次这么做呢

  • 我想我知道为什么,密钥生成一次用于在缓存中查找,一次用于放入缓存。不知道为什么会这样,但似乎是发生了什么。

    你能发布关于如何调用getCountOfCustomers(list)方法的代码吗?@jay,我已经发布了用于调用的代码,并注意到我调用了两次。现在我调用\@Cacheable注释的方法一次,但看到keyGenerator运行了两次。我想我知道为什么,一次生成一个密钥用于在缓存中查找,一次用于放入缓存。我认为您的密钥不是唯一的,这可能是原因之一,您可能希望尝试更改不同的generate()方法。有人发现这是“正常”行为吗?我注意到了同样的行为,我的钥匙绝对是独一无二的。
    curl http://127.0.0.1:8080/countCustomers
     % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100    18  100    18    0     0     18      0  0:00:01 --:--:--  0:00:01    
    76countOfCustomers=2
    
    ...
    2018-08-27 11:56:53.753  INFO 18756 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
    2018-08-27 11:56:53.757  INFO 18756 --- [           main] c.example.demo.TestCacheableApplication  : Started TestCacheableApplication in 3.543 seconds (JVM running for 5.137)
    2018-08-27 11:56:58.411  INFO 18756 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
    2018-08-27 11:56:58.411  INFO 18756 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
    2018-08-27 11:56:58.446  INFO 18756 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 35 ms
    Generating a key
    2018-08-27 11:56:58.480 TRACE 18756 --- [nio-8080-exec-1] o.s.cache.interceptor.CacheInterceptor   : Computed cache key '104328221' for operation Builder[public int com.example.demo.CustomerService.getCountOfCustomers(java.util.ArrayList)] caches=[customersCache] | key='' | keyGenerator='customerKeyGenerator' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'
    2018-08-27 11:56:58.480 TRACE 18756 --- [nio-8080-exec-1] o.s.cache.interceptor.CacheInterceptor   : No cache entry for key '104328221' in cache(s) [customersCache]
    Generating a key
    2018-08-27 11:56:58.480 TRACE 18756 --- [nio-8080-exec-1] o.s.cache.interceptor.CacheInterceptor   : Computed cache key '104328221' for operation Builder[public int com.example.demo.CustomerService.getCountOfCustomers(java.util.ArrayList)] caches=[customersCache] | key='' | keyGenerator='customerKeyGenerator' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'