Spring์—์„œ ์บ์‹œ ์‚ฌ์šฉํ•˜๊ธฐ: CaffeineCache, @Cacheable, @CachePut, @CacheEvict

2025. 6. 12. 16:48ยท๐ŸŒฟSpring
๋ชฉ์ฐจ
  1. โ˜• Caffeine Cache
  2. โœ… @Cacheable
  3. โœ…  @CachePut
  4. โœ…  @CacheEvict

๐Ÿ”– ๋จผ์ € ์ฝ์œผ๋ฉด ์ข‹์€ ๊ธ€

 

๋กœ์ปฌ ์บ์‹œ & ๋ถ„์‚ฐ ์บ์‹œ ์ดํ•ดํ•˜๊ธฐ

๐Ÿ”– ๋จผ์ € ์ฝ์œผ๋ฉด ์ข‹์€ ๊ธ€ ์บ์‹œ(Cache) ๊ฐœ๋… ์‰ฝ๊ฒŒ ์ •๋ฆฌํ•˜๊ธฐ๐Ÿš€ ์บ์‹œ(Cache)๋ž€?์ง€๊ธˆ๊นŒ์ง€ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ง์ ‘ ์กฐํšŒํ•ด์™”์Šต๋‹ˆ๋‹ค.๊ฐœ๋ฐœ์„ ๊ณต๋ถ€ํ•ด๋ดค๋‹ค๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ฑ๋Šฅ์€ I/O ์ž‘

syleeblog.tistory.com

์Šคํ”„๋ง ํ”„๋กœ์ ํŠธ์—์„œ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ์ˆ  ์ค‘ ํ•˜๋‚˜๊ฐ€ ์บ์‹œ์ž…๋‹ˆ๋‹ค.

 

์ง€๋‚œ ๊ธ€๋“ค์—์„œ ์บ์‹œ ๊ฐœ๋…์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์Šคํ”„๋ง ํ”„๋กœ์ ํŠธ์— ๋กœ์ปฌ ์บ์‹œ๋ฅผ ์ ์šฉํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€ํ‘œ์ ์ธ ๋กœ์ปฌ ์บ์‹œ Caffeine์„ ์ ์šฉํ•˜๊ณ , @Cacheable, @CachePut, @CacheEvict์™€ ๊ฐ™์€ ์Šคํ”„๋ง์˜ ์บ์‹œ ์–ด๋…ธํ…Œ์ด์…˜์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ด…์‹œ๋‹ค.


โš™๏ธ ํ™˜๊ฒฝ

  • SpringBoot 3.4.0
  • build.gradle์— dependency ์ถ”๊ฐ€
// Cache
implementation 'org.springframework.boot:spring-boot-starter-cache'

 

์ด ๊ธ€์—์„œ๋Š” ๋กœ์ปฌ ์บ์‹œ ์ค‘ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์บ์‹œ ์ค‘ ํ•˜๋‚˜์ธ Caffeine ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.


โ˜• Caffeine Cache

์นดํŽ˜์ธ ์บ์‹œ๋Š” Java์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ณ ์„ฑ๋Šฅ ๋กœ์ปฌ ์บ์‹œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ

๋น ๋ฅธ ์†๋„์™€ ๋†’์€ ์ ์ค‘๋ฅ , ๊ทธ๋ฆฌ๊ณ  ๋‹ค์–‘ํ•œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๋ฉฐ Spring์—์„œ๋„ ๊ณต์‹์ ์œผ๋กœ ์ง€์›ํ•˜๋Š” ์ข‹์€ ์บ์‹œ์ž…๋‹ˆ๋‹ค.

 

์นดํŽ˜์ธ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”.

 

build.gradle

implementation 'com.github.ben-manes.caffeine:caffeine'

 

๊ทธ๋ฆฌ๊ณ  Configuration ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ด์ค์‹œ๋‹ค.

 

Cache Configuration

@Configuration
@EnableCaching
@Slf4j
class CacheConfig {

    @Bean
    public CaffeineCacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager("users", "notifications");
        cacheManager.setCaffeine(caffeineCacheBuilder());
        return cacheManager;
    }

    @Bean
    public Caffeine<Object, Object> caffeineCacheBuilder() {
        return Caffeine.newBuilder()
            .expireAfterWrite(30, TimeUnit.MINUTES) // ์“ฐ๊ณ  30๋ถ„ ํ›„ ๋งŒ๋ฃŒ
            .expireAfterAccess(10, TimeUnit.MINUTES)    // ๋ฌด์‚ฌ์šฉ 10๋ถ„ ํ›„ ๋งŒ๋ฃŒ
            .maximumSize(5000)  // ์ตœ๋Œ€ ์—”ํŠธ๋ฆฌ ์ˆ˜
            .recordStats()  // ํ†ต๊ณ„ ์ˆ˜์ง‘ ํ™œ์„ฑํ™”
            .removalListener((key, value, cause) -> // ์ œ๊ฑฐ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ
                log.info("Cache removed: key={}, cause={}", key, cause));
    }
 }

 

๐Ÿง‘โ€๐Ÿ’ผ ์บ์‹œ ๋งค๋‹ˆ์ €(Cache Manager)๋ž€?

์บ์‹œ ๋งค๋‹ˆ์ €๋Š” ์Šคํ”„๋ง์—์„œ ์—ฌ๋Ÿฌ ์บ์‹œ ์ธ์Šคํ„ด์Šค๋ฅผ ํ†ตํ•ฉ ๊ด€๋ฆฌํ•˜๋Š” ํ•ต์‹ฌ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.

์–ด๋–ค ์บ์‹œ๋ฅผ ์–ด๋–ค ์ด๋ฆ„์œผ๋กœ ์ƒ์„ฑํ• ์ง€, ์ •์ฑ…์€ ์–ด๋–ป๊ฒŒ ์ ์šฉํ• ๊ฑด์ง€ ๊ฒฐ์ •ํ•˜์ฃ .

 

CaffeineCacheManager๋Š” CacheManager์˜ ๊ตฌํ˜„์ฒด ์ค‘ ํ•˜๋‚˜๋กœ, ์šฐ๋ฆฌ๋Š” ์นดํŽ˜์ธ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋‹ˆ ์ด ๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์บ์‹œ๋ฅผ ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค์ •ํ•˜์—ฌ setCaffeine() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์„ค์ •์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

โ˜• ์นดํŽ˜์ธ ์บ์‹œ ์ƒ์„ธ ์„ค์ •

  • ๋งŒ๋ฃŒ ์ •์ฑ…
    • expireAfterWrite: ๋ฐ์ดํ„ฐ๊ฐ€ ์ƒ์„ฑ/์ˆ˜์ •๋œ ํ›„ 30๋ถ„์ด ์ง€๋‚˜๋ฉด ์บ์‹œ์—์„œ ์ž๋™ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค. ์บ์‹œ์— ์ €์žฅํ•œ์ง€ ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ๋Š” ํ‹€๋ฆด ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
    • expireAfterAccess: 10๋ถ„ ๋™์•ˆ ์ ‘๊ทผ์ด ์—†์œผ๋ฉด ๋ถˆํ•„์š”ํ•œ ์บ์‹ฑ์ด๋ผ ๊ฐ„์ฃผํ•˜์—ฌ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.
  • ์šฉ๋Ÿ‰ ๊ด€๋ฆฌ
    • maximumSize(5000): ์บ์‹œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌดํ•œ์œผ๋กœ ์ €์žฅ๋˜์ง€ ์•Š๋„๋ก ์ตœ๋Œ€ 5000๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋งŒ ์ €์žฅํ•˜๋„๋ก ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.
      • ๋กœ์ปฌ ์บ์‹œ๋Š” ์„œ๋ฒ„ ๋ฉ”๋ชจ๋ฆฌ ๋‚ด์— ์œ„์น˜ํ•˜๋ฏ€๋กœ ์šฉ๋Ÿ‰์ด ๋„ˆ๋ฌด ํฌ๋ฉด ์„œ๋ฒ„ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      • ๋ฐ์ดํ„ฐ ์ดˆ๊ณผ๋กœ ์ธํ•ด ์‚ญ์ œ ์‹œ LRU(Least Recently Used) ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋”ฐ๋ผ ์‚ฌ์šฉํ•œ์ง€ ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ๋ถ€ํ„ฐ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋‹ˆํ„ฐ๋ง
    • recordStats(): ์บ์‹œ ์ ์ค‘๋ฅ  ํ†ต๊ณ„๋ฅผ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค.
      • cacheManager.getCache("users").getStats()๋กœ ์ ์ค‘๋ฅ  ํ™•์ธ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

removalListener: ์บ์‹œ ์‚ญ์ œ ์›์ธ(๋งŒ๋ฃŒ, ์ˆ˜๋™ ์‚ญ์ œ ๋“ฑ)์„ ๋กœ๊น…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์บ์‹œ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด ์†์‰ฝ๊ฒŒ ์บ์‹œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœ… @Cacheable

@Cacheable ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ฉ”์„œ๋“œ ์œ„์— ๋ถ™์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•˜๊ณ ,

๊ฐ™์€ ์ธ์ž๋กœ ์žฌํ˜ธ์ถœ ์‹œ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€ ๋กœ์ง์ด ์‹คํ–‰๋˜์ง€ ์•Š๊ณ , ์บ์‹œ์—์„œ ๋ฐ”๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

// ์œ ์ €๋ณ„๋กœ ์•Œ๋ฆผ ๋ชฉ๋ก์„ ์กฐํšŒํ•˜๋Š” ์„œ๋น„์Šค ๋ฉ”์„œ๋“œ
// userId๋ฅผ ํ‚ค๋กœ ์ €์žฅ๋˜์–ด, userId๋งˆ๋‹ค ๋ชฉ๋ก ์กฐํšŒ ๊ฒฐ๊ณผ๊ฐ€ ์บ์‹ฑ๋จ

@Cacheable(
    cacheNames = "notifications",
    key = "#userId"
)
public List<NotificationDto> findAll(UUID userId) {
    List<Notification> notifications = notificationRepository.findAllByReceiverId(userId);
    return notificationMapper.toDto(notifications);
}

 

์ฃผ์š” ์†์„ฑ

 

cacheNames ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์บ์‹œ ์ €์žฅ์†Œ ์ด๋ฆ„
key ์บ์‹œ ํ‚ค ์ง€์ •(๊ธฐ๋ณธ์ ์œผ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ ์กฐํ•ฉ์œผ๋กœ ๋งŽ์ด ํ•จ)
condition ์บ์‹ฑ ์ ์šฉ ์กฐ๊ฑด(๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „์— ์กฐ๊ฑด์— ๋ถ€ํ•ฉํ•˜๋Š”์ง€ ํ‰๊ฐ€ํ•จ)
unless ์บ์‹ฑ ์ œ์™ธ ์กฐ๊ฑด(๋ฉ”์„œ๋“œ ์‹คํ–‰ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹ฑํ• ์ง€ ํ‰๊ฐ€ํ•จ)
sync ๋™๊ธฐํ™” ์บ์‹œ ์กฐํšŒ ๊ธฐ๋Šฅ ํ™œ์„ฑํ™”
  • ์บ์‹œ ์Šคํƒฌํ”ผ๋“œ(Cache Stampede) ํ˜„์ƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์†์„ฑ์ž…๋‹ˆ๋‹ค.
  • ์บ์‹œ ์Šคํƒฌํ”ผ๋“œ: ์บ์‹œ๊ฐ€ ๋งŒ๋ฃŒ๋˜๊ฑฐ๋‚˜ ๋ฏธ์Šค๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์—ฌ ์ผ์‹œ์ ์œผ๋กœ DB ๊ณผ๋ถ€ํ•˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `sync = true` ์˜ต์…˜์œผ๋กœ ์ด๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๊ฐ™์€ ํ‚ค๋กœ ์บ์‹œ๋ฅผ ์กฐํšŒํ•  ๋•Œ ์ฒซ ๋ฒˆ์งธ ์Šค๋ ˆ๋“œ๋งŒ ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ , ๋‚˜๋จธ์ง€ ์Šค๋ ˆ๋“œ๋Š” ์บ์‹ฑ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•ฉ๋‹ˆ๋‹ค.
  •  

๋” ๋‹ค์–‘ํ•œ ์†์„ฑ์„ ์จ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

SpEL(Spring Expression Language) ๋ฌธ๋ฒ•์— ๋”ฐ๋ผ ์ž‘์„ฑํ•˜๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@Cacheable(
    cacheNames = "notifications",
    key = "#userId"
    condition= "#userId!=null"	// userId๊ฐ€ null์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ์บ์‹ฑ ์ ์šฉ 
    unless = "#result.getSize() == 0"	// ์กฐํšŒํ•œ ๊ฒฐ๊ณผ ์•Œ๋ฆผ ๊ฐœ์ˆ˜๊ฐ€ 0๊ฐœ์ธ ๊ฒฝ์šฐ ์บ์‹ฑ ์ œ์™ธ
)
public List<NotificationDto> findAll(UUID userId) {
    List<Notification> notifications = notificationRepository.findAllByReceiverId(userId);
    return notificationMapper.toDto(notifications);
}

โœ…  @CachePut

๋ฉ”์„œ๋“œ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฌด์กฐ๊ฑด ์บ์‹œ์— ์ €์žฅ(๊ฐฑ์‹ )ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ž…๋‹ˆ๋‹ค.

@Cacheable์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „, ์บ์‹œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ

@CachePut์€ ํ•ญ์ƒ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์œ ์ €๋ณ„๋กœ ๋งˆ์ดํŽ˜์ด์ง€๋ฅผ ๋น ๋ฅด๊ฒŒ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•ด

์œ ์ € ์ •๋ณด DTO๋ฅผ ์กฐํšŒํ•˜๋Š” ๋ฉ”์„œ๋“œ์— @Cacheable์„ ์ ์šฉํ–ˆ๋‹ค๊ณ  ํ•ฉ์‹œ๋‹ค.

@Cacheable(
    cacheNames = "users",
    key = "#userId"
)
public UserDto find(UUID userId) {
	User user = userRepository.findById(userId)
	    .orElseThrow(() -> new UserNotFoundException(Map.of("userId", userId)));
    return userMapper.toDto(user);
}

 

๊ทธ๋ ‡๋‹ค๋ฉด ํ”„๋กœํ•„ ์ด๋ฏธ์ง€๋‚˜ ์—ฐ๋ฝ์ฒ˜๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค๋“ ์ง€ ์œ ์ € ์ •๋ณด๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜๋ฉด ์–ด๋–จ๊นŒ์š”?

์บ์‹œ์— ์žˆ๋Š” ์ •๋ณด๋Š” ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋˜์–ด ํ•„์š”์—†๊ฒŒ ๋˜๊ณ , ๊ฐฑ์‹ ์ด ํ•„์š”ํ•ด์ง‘๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ์œ ์ € ์ •๋ณด๊ฐ€ ์—…๋ฐ์ดํŠธ๋  ๋•Œ๋งˆ๋‹ค ์บ์‹œ์—์„œ ํ•ด๋‹น ํ‚ค๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๋„๋ก @CachePut์„ ์ด์šฉํ•ฉ์‹œ๋‹ค.

๊ฒฐ๊ณผ๋กœ ๋ฐ˜ํ™˜๋˜๋Š” ์œ ์ € ์ •๋ณด๊ฐ€ ์บ์‹œ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

@CachePut(
    cacheNames = "users",
    key = "#userUpdateRequest.userId"
)
public UserDto update(UUID userId, UserUpdateRequest userUpdateRequest,
    // User ์—”ํ‹ฐํ‹ฐ ์—…๋ฐ์ดํŠธ ๋กœ์ง
    return userMapper.toDto(user);
}

โœ…  @CacheEvict

์บ์‹œ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์‹ค์ œ ๋ฐ์ดํ„ฐ์™€ ์บ์‹œ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ถˆ์ผ์น˜๊ฐ€ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ

์ ์ ˆํ•œ๊ฒŒ @CacheEvict๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฉ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์•„๊นŒ ์œ ์ €๋ณ„ ์ •๋ณด๋ฅผ ๋น ๋ฅด๊ฒŒ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•ด ์บ์‹ฑํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋งŒ์•ฝ ๊ทธ ์œ ์ €๊ฐ€ ์‚ญ์ œ๋œ๋‹ค๋ฉด ์บ์‹œ์—์„œ๋Š” ๋” ์ด์ƒ ํ•„์š”์—†๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋˜๊ฒ ์ฃ ?

@CacheEvict๋ฅผ ํ†ตํ•ด ์บ์‹œ์—์„œ ํ•ด๋‹น ์—”ํŠธ๋ฆฌ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

@CacheEvict(cacheNames = "users", key = "#userId")
public void delete(UUID userId) {
    User user = userRepository.findById(userId).orElseThrow(() -> {
        log.warn("[Updating User Failed: User with id {} not found]", userId);
        return new UserNotFoundException(Map.of("userId", userId));
    });
    userRepository.delete(user);
}

 

์ฃผ์š” ์†์„ฑ

cacheNames ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•  ์บ์‹œ ์ €์žฅ์†Œ ์ด๋ฆ„
key ์บ์‹œ ํ‚ค ์ง€์ •(๊ธฐ๋ณธ์ ์œผ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ ์กฐํ•ฉ์œผ๋กœ ๋งŽ์ด ํ•จ)
allEnrites = true ํŠน์ • ์—”ํŠธ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ผ ์บ์‹œ ๋‚ด ๋ชจ๋“  ์—”ํŠธ๋ฆฌ ์‚ญ์ œ
beforeInvocation true์ด๋ฉด ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „์— ์บ์‹œ์—์„œ ์‚ญ์ œ
false์ด๋ฉด ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์„ฑ๊ณต ํ›„์— ์‚ญ์ œ

  • true์ด๋ฉด ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „์— ์‚ญ์ œ๋˜๋ฏ€๋กœ ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ค‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ ์บ์‹œ์—์„œ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๋˜์ง€๋งŒ
    false์ด๋ฉด ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ค‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์บ์‹œ์—์„œ ์‚ญ์ œ๋˜์ง€ ์•Š์Œ
condition ์บ์‹œ์—์„œ ์ œ๊ฑฐํ•˜๋Š” ์กฐ๊ฑด

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Spring์—์„œ ๋กœ์ปฌ ์บ์‹œ๋กœ Caffeine์„ ์„ค์ •ํ•˜๊ณ ,
์บ์‹œ ๊ด€๋ จ ์–ด๋…ธํ…Œ์ด์…˜๋“ค์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ๊ธฐ๋ณธ์ ์ธ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์•ž์œผ๋กœ์˜ ํ”„๋กœ์ ํŠธ์—์„œ ์ž์ฃผ ์บ์‹œ๋ฅผ ์ ์šฉํ•  ๊ฒƒ ๊ฐ™์•„์š”!

 

์ฐธ๊ณ ์ž๋ฃŒ

Spring boot ์— caffeine ์บ์‹œ๋ฅผ ์ ์šฉํ•ด๋ณด์ž - ์–ด๋–ป๊ฒŒํ•˜๋ฉด ์ผ์„ ์•ˆ ํ• ๊นŒ?

Spring Boot ์—์„œ Cache ์‚ฌ์šฉํ•˜๊ธฐ

 

 

 

 

๋ฐ˜์‘ํ˜•

'๐ŸŒฟSpring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Spring] DI(Dependency Injection) ์˜์กด์„ฑ ์ฃผ์ž…  (4) 2025.08.14
[Spring] IoC ์ œ์–ด์˜ ์—ญ์ „  (1) 2025.08.12
JWT(Json Web Token) ๊ตฌ์กฐ ์ดํ•ดํ•˜๊ธฐ  (0) 2025.05.25
[Spring Security] ์›น ๋ณด์•ˆ ๊ณต๊ฒฉ #2 ์„ธ์…˜ ๊ณ ์ • ๊ณต๊ฒฉ, JWT ํ† ํฐ ํƒˆ์ทจ + ๋Œ€์‘ ์ „๋žต  (0) 2025.05.23
[Spring Security] ์›น ๋ณด์•ˆ ๊ณต๊ฒฉ #1: CSRF๊ณต๊ฒฉ๊ณผ XSS ๊ณต๊ฒฉ + ๋Œ€์‘ ์ „๋žต  (1) 2025.05.23
  1. โ˜• Caffeine Cache
  2. โœ… @Cacheable
  3. โœ…  @CachePut
  4. โœ…  @CacheEvict
'๐ŸŒฟSpring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [Spring] DI(Dependency Injection) ์˜์กด์„ฑ ์ฃผ์ž…
  • [Spring] IoC ์ œ์–ด์˜ ์—ญ์ „
  • JWT(Json Web Token) ๊ตฌ์กฐ ์ดํ•ดํ•˜๊ธฐ
  • [Spring Security] ์›น ๋ณด์•ˆ ๊ณต๊ฒฉ #2 ์„ธ์…˜ ๊ณ ์ • ๊ณต๊ฒฉ, JWT ํ† ํฐ ํƒˆ์ทจ + ๋Œ€์‘ ์ „๋žต
์†Œ์˜ ๐Ÿ€
์†Œ์˜ ๐Ÿ€
Hello World โœจ
  • ์†Œ์˜ ๐Ÿ€
    Soyoung's Dev Lab
    ์†Œ์˜ ๐Ÿ€
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
  • ๊ธ€์“ฐ๊ธฐ ๊ด€๋ฆฌ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (75) N
      • ๐Ÿ“ข ๊ฒŒ์‹œํŒ (0)
      • ๐ŸŒฟSpring (20) N
      • โ˜•Java (10)
      • โš™๏ธ CS (26)
        • ๐Ÿ›œ ๋„คํŠธ์›Œํฌ (5)
        • ๐Ÿ“Š ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (8)
        • ๐Ÿ–ฒ๏ธ์šด์˜์ฒด์ œ (9)
        • ๐Ÿ“š ์ž๋ฃŒ๊ตฌ์กฐ & ์•Œ๊ณ ๋ฆฌ์ฆ˜ (4)
      • ๐Ÿ“ค ๋ฐฐํฌ (4)
        • Docker (4)
        • AWS (0)
      • ๐Ÿ“ฐ ๊ธฐํƒ€ ๊ฐœ๋ฐœ ์ž๋ฃŒ (12)
      • ๐Ÿ–ฅ๏ธ ํ”„๋กœ์ ํŠธ (0)
      • ๐Ÿ‘ฉโ€๐Ÿ’ป ํ™œ๋™ & ํ›„๊ธฐ (1)
      • ๐Ÿต ์ด์•ผ๊ธฐ (2)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํƒœ๊ทธ
  • ๋งํฌ

    • github
    • velog
  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ์œ„ํด๋ฆฌ ํŽ˜์ดํผ
    ๋„คํŠธ์›Œํฌ
    Spring
    docker
    ์•Œ๊ณ ๋ฆฌ์ฆ˜
    ์„œ๋ฒ„
    Spring Security
    ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค
    ๊ธฐ์ˆ  ๋ฉด์ ‘
    ๊ฐ์ฒด์ง€ํ–ฅํ”„๋กœ๊ทธ๋ž˜๋ฐ
    GIT
    ์šด์˜์ฒด์ œ
    ๋ฐฐํฌ
    ์ž๋ฃŒ๊ตฌ์กฐ
    ์ฝ”๋”ฉํ…Œ์ŠคํŠธ
    ๊ฐœ๋ฐœ
    Java
    ์ฝ”๋“œ์ž‡ ์Šคํ”„๋ฆฐํŠธ
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
์†Œ์˜ ๐Ÿ€
Spring์—์„œ ์บ์‹œ ์‚ฌ์šฉํ•˜๊ธฐ: CaffeineCache, @Cacheable, @CachePut, @CacheEvict

๊ฐœ์ธ์ •๋ณด

  • ํ‹ฐ์Šคํ† ๋ฆฌ ํ™ˆ
  • ํฌ๋Ÿผ
  • ๋กœ๊ทธ์ธ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”

๋‹จ์ถ•ํ‚ค

๋‚ด ๋ธ”๋กœ๊ทธ

๋‚ด ๋ธ”๋กœ๊ทธ - ๊ด€๋ฆฌ์ž ํ™ˆ ์ „ํ™˜
Q
Q
์ƒˆ ๊ธ€ ์“ฐ๊ธฐ
W
W

๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๊ธ€

๊ธ€ ์ˆ˜์ • (๊ถŒํ•œ ์žˆ๋Š” ๊ฒฝ์šฐ)
E
E
๋Œ“๊ธ€ ์˜์—ญ์œผ๋กœ ์ด๋™
C
C

๋ชจ๋“  ์˜์—ญ

์ด ํŽ˜์ด์ง€์˜ URL ๋ณต์‚ฌ
S
S
๋งจ ์œ„๋กœ ์ด๋™
T
T
ํ‹ฐ์Šคํ† ๋ฆฌ ํ™ˆ ์ด๋™
H
H
๋‹จ์ถ•ํ‚ค ์•ˆ๋‚ด
Shift + /
โ‡ง + /

* ๋‹จ์ถ•ํ‚ค๋Š” ํ•œ๊ธ€/์˜๋ฌธ ๋Œ€์†Œ๋ฌธ์ž๋กœ ์ด์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ํ‹ฐ์Šคํ† ๋ฆฌ ๊ธฐ๋ณธ ๋„๋ฉ”์ธ์—์„œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.