Handbooks / Spring Boot / Chapter 8
Caching, Async and Scheduling
7 pages · ~5 min✓ Reviewed
Builds on Spring Security. Next up: Messaging and HTTP Clients.
Caching, Async and Scheduling Mental Model
1. Proxy-Based AOP
- Calleranother bean
- Spring proxyintercepts call
- Extra behaviourcache, thread, timer
- Real methodyour code
- Opt-in switches on a @Configuration class:
@EnableCaching,@EnableAsync,@EnableScheduling - No switch = annotations silently ignored
2. When the Proxy Is Skipped
this.method()self-invocation:@Cacheable,@Async,@Transactionaldo nothingprivatemethods are not intercepted; use publicfinalclass or method cannot be proxied- Object must be a Spring-managed bean, not
new
java
public User first() {
return this.get(1L); // no proxy
}
@Cacheable("users")
public User get(long id) { ... }get() always runs; call it from another bean
3. Cache Facade
- CacheManager hands out named
Cacheobjects - Provider is swappable; annotated code stays unchanged
- @Cacheableannotation
- CacheManagerfacade
- Cache usersnamed cache
- Caffeine or Redisprovider
Go through the proxy
Call the annotated method from another bean. A call inside the same class is never intercepted.
Cacheable, CacheEvict and CachePut Workflow
1. The @Cacheable flow
- Callthrough proxy
- Lookupcache + key
- Hitbody skipped
- Missrun, then store
@Cacheable("users")checks the cache first- Default key = all arguments (
SimpleKeyif none) - Override with SpEL:
key = "#id"orkey = "#user.id"
2. Three annotations
| Annotation | Method runs? | Cache effect |
|---|---|---|
@Cacheable | only on a miss | reads, or fills |
@CachePut |
Cache Providers: Caffeine vs Redis
1. Two Providers
| Caffeine | Redis | |
|---|---|---|
| Where | In-process | Out-of-process, shared |
| Speed | Fastest, no network hop | Network + serialization cost |
| Instances | Own copy each, entries drift | Consistent across instances |
| Restart | Cache lost | Survives |
2. Configuration
- Caffeine: one spec string sets size and expiry
Async Methods and Executors
1. What @Async Does
- On a public bean method: returns immediately, body runs on an executor thread
- Return
void,FutureorCompletableFuture<T>
- Callercalls proxy
- Proxysubmits task
- Executor threadruns body
2. Executors
| Setting | Value |
|---|---|
| Default bean | applicationTaskExecutor (ThreadPoolTaskExecutor) |
| Default sizing | core 8, queue unbounded |
| Named pool |
Scheduled Tasks and Thread Pool Pitfalls
1. Triggers
| Attribute | Timing |
|---|---|
fixedRate=5000 | every 5s, start to start |
fixedDelay=5000 | 5s after the previous run finishes |
initialDelay | postpones the first run |
java
@Scheduled(cron = "0 0 2 * * *", zone = "Asia/Kolkata")
second minute hour day month weekday: daily 02:00 in that zone
2. Pool pitfalls
- Default scheduler is single-threaded: one slow job delays all others
- Fix:
spring.task.scheduling.pool.sizeor aTaskSchedulerbean
Spring Caching, Async and Scheduling Cheat Sheet
1. Switches and the proxy
@EnableCaching,@EnableAsync,@EnableSchedulingon a @Configuration class- Calls must go through the proxy:
this.method()skips it - Method is public on a Spring bean
2. Cache annotations and providers
| Annotation | Does |
|---|---|
@Cacheable | reads, or runs and fills |
@CachePut | always runs, refreshes |
@CacheEvict(allEntries=true) | clears the cache |
Check yourself
twice(1) calls get(1) two times inside the same bean, and get has @Cacheable. How many times does the body of get run?
- Twice:
this.get()bypasses the proxy - No cache lookup happens, so nothing is ever stored
- Fix: call from another bean, or move
getout
@Cacheable("x") public int get(int id) { ... } public int twice(int id) { return get(id) + get(id); }
An executor has core 2, max 10 and the default queue. You submit 20 slow tasks. How many threads run?
- Only 2: the default queue is unbounded and never fills
- So the pool never grows past core, and
maxis ignored - Set
queueCapacityto let it grow
A fixedRate=5000 job takes 8s on the default single-threaded scheduler. When does each run start?
- Every ~8s, right when the previous run ends