Summary: In the current implementation of cache annotation parsing in SpringCacheAnnotationParser , the code processes annotation collections multiple times using separate streams — once for each annotation type (@Cacheable, @CacheEvict, @CachePut, @Caching). This results in multiple iterations over the same collection and creates several short-lived stream pipelines.

Current code example:

annotations.stream().filter(Cacheable.class::isInstance).map(Cacheable.class::cast).forEach(
        cacheable -> ops.add(parseCacheableAnnotation(ae, cachingConfig, cacheable)));
annotations.stream().filter(CacheEvict.class::isInstance).map(CacheEvict.class::cast).forEach(
        cacheEvict -> ops.add(parseEvictAnnotation(ae, cachingConfig, cacheEvict)));
annotations.stream().filter(CachePut.class::isInstance).map(CachePut.class::cast).forEach(
        cachePut -> ops.add(parsePutAnnotation(ae, cachingConfig, cachePut)));
annotations.stream().filter(Caching.class::isInstance).map(Caching.class::cast).forEach(
        caching -> parseCachingAnnotation(ae, cachingConfig, caching, ops));

This effectively loops over the same annotations collection four times, creating four independent stream pipelines.

Suggested improvement Iterate over the annotations only once, using either a classic loop or a single stream with conditional branching.

This approach: - Reduces the number of iterations from 4 to 1 - Avoids multiple stream creations and lambda allocations - Keeps functional behavior identical

Comment From: jhoeller

Superseded by PR #35599.