Given the following method with the Cacheable annotation:
@Cacheable(value = "cachekey", key = "#taskId")
public Task getTask(Long taskId) {
log.info("called");
Task task = ...;
return task;
}
And the following configuration:
@EnableCaching
@Configuration
public class CacheConfiguration {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("cachekey");
}
@Scheduled(fixedDelay = 30000)
@CacheEvict(allEntries = true, cacheNames = {"cachekey"})
public void cacheEvict() {
}
}
And the following pom parts:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/>
</parent>
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
By calling getTask, I always hit the method and no request is served from the cache itself.
What am I doing wrong?
I've recreated an application based off the code you provided and tried to keep it as similar as possible. The program yields the output:
Calling getTask
getTask called
Calling getTask again
true
Which indicates that getTask
is only executed once and that the caching is working. So we'll have to assume it is something not listed in the code you provided. Two thoughts come to mind:
#getTask(Long)
when calling it multiple times? As it's currently configured, different longs will result in different cache entries. You'll have to call it at least twice with the same long in order to see caching take effect.#getTask(Long)
from a different bean than the one which contains #getTask(Long)
? The functionality provided by @Cacheable
is implemented using Spring AOP. Spring AOP will wrap the bean ( CachedService
in my example) with some generated code that handles the cache retrieval and put. However, this wrapping does not affect method calls internal to that bean. For example, if I added a #getTask99()
method to CachedService
like in the code snippet below:
@Component
public static class CachedService {
public Task getTask99() {
return getTask(99L);
}
@Cacheable(value = "cachekey", key = "#taskId")
public Task getTask(Long taskId) {
System.out.println("getTask called");
Task task = new Task(System.out::println);
return task;
}
}
Calling #getTask99()
produces:
Calling getTask99
getTask called
Calling getTask99 again
getTask called
false
Indicating that nothing was cached, as the bean wrapping has been circumvented. Instead, call #getTask(99L)
from a different bean, like CacheTestRunner
in my example.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.