Avatar
πŸ˜‰

Organizations

  • Mock, Stub 의 차이

    mockκ³Ό stub은 ν…ŒμŠ€νŠΈμ—μ„œ μ™ΈλΆ€ μ˜μ‘΄μ„±μ„ λŒ€μ²΄ν•˜κΈ° μœ„ν•΄ μ“°μ΄λŠ” 객체인데, λ‘˜μ€ λͺ©μ κ³Ό κΈ°λŠ₯ λ©΄μ—μ„œ 쑰금 λ‹¬λΌμš”.


    πŸ“Œ μš”μ•½ 비ꡐ

    ν•­λͺ© Stub Mock
    λͺ©μ  κ³ μ •λœ κ°’ λ°˜ν™˜ (λ‹¨μˆœ λŒ€μ²΄) λ™μž‘ 검증 + μœ μ—°ν•œ μ„€μ •
    κΈ°λŠ₯ 미리 μ •μ˜λœ 응닡 제곡 호좜 μ—¬λΆ€, 호좜 횟수, νŒŒλΌλ―Έν„° 검증 λ“± κ°€λŠ₯
    ν…ŒμŠ€νŠΈ νƒ€μž… 주둜 μƒνƒœ 기반 ν…ŒμŠ€νŠΈ (State-based) 주둜 ν–‰μœ„ 기반 ν…ŒμŠ€νŠΈ (Behavior-based)
    μ˜ˆμ‹œ “이 λ©”μ„œλ“œκ°€ 호좜되면 무쑰건 이 값을 리턴” “이 λ©”μ„œλ“œκ°€ μ •ν™•νžˆ ν•œ 번 ν˜ΈμΆœλλŠ”μ§€ ν™•μΈν•˜μž”

    πŸ”Ή Stub: λ‹¨μˆœν•˜κ²Œ λ¦¬ν„΄κ°’λ§Œ 정해놓은 κ°€μ§œ

    • μ‹€μ œ λ©”μ„œλ“œ λ‘œμ§μ€ ν•„μš” μ—†κ³ , “이 값을 μ£Όλ©΄ 이 값을 돌렀쀘!” 같은 κ°„λ‹¨ν•œ λŒ€μ²΄ν’ˆ.
    • 주둜 “κΈ°μ‘΄ μ‹œμŠ€ν…œμ—μ„œ 이거만 μ œλŒ€λ‘œ λ™μž‘ν•˜λ©΄ 돼"λΌλŠ” ν…ŒμŠ€νŠΈμ— μ‚¬μš©.
    when(userRepository.findById(1L)).thenReturn(Optional.of(user));
    

    πŸ”Έ Mock: ν–‰μœ„(호좜 μ—¬λΆ€ λ“±)κΉŒμ§€ ν™•μΈν•˜λŠ” κ°€μ§œ

    • 리턴값도 μ •μ˜ν•  수 μžˆμ§€λ§Œ, “μ •λ§λ‘œ 이 λ©”μ„œλ“œκ°€ ν˜ΈμΆœλλŠ”κ°€?” 같은 검증도 κ°€λŠ₯.
    • verify() 같은 λ©”μ„œλ“œλ₯Ό 톡해 ν…ŒμŠ€νŠΈμ˜ 정확성을 λ†’μž„.
    verify(userRepository, times(1)).findById(1L);
    

    βœ… μ‹€μ œ ν…ŒμŠ€νŠΈ μ˜ˆμ‹œ

    @Mock
    UserRepository userRepository;
    
    @InjectMocks
    UserService userService;
    
    @Test
    void testUserFetch() {
        // Stub: 리턴값 μ§€μ •
        when(userRepository.findById(1L)).thenReturn(Optional.of(new User("Alice")));
    
        // λ©”μ„œλ“œ μ‹€ν–‰
        User user = userService.getUser(1L);
    
        // Mock: 호좜 μ—¬λΆ€ 검증
        verify(userRepository, times(1)).findById(1L);
    }
    

    πŸ“Ž 간단 λΉ„μœ 

    • Stub: β€œλˆ„κ°€ 와도 무쑰건 이 λŒ€μ‚¬λ§Œ 말해!”
    • Mock: β€œλˆ„κ°€ 였면 이 λŒ€μ‚¬λ₯Ό ν•˜κ³ , μ œλŒ€λ‘œ λ§ν–ˆλŠ”μ§€ 검사도 ν•©λ‹ˆλ‹€.!”

    Created Thu, 03 Apr 2025 15:57:29 +0900
  • ν…ŒμŠ€νŠΈ 더블(Test Double) μš©μ–΄ 정리

    • μ•„λž˜λŠ” ν…ŒμŠ€νŠΈμ—μ„œ 자주 μ“°μ΄λŠ” 5κ°€μ§€ ν…ŒμŠ€νŠΈ λŒ€μ—­μž…λ‹ˆλ‹€:

    πŸ§ͺ ν…ŒμŠ€νŠΈ 더블(Test Double) μ’…λ₯˜ μš”μ•½

    νƒ€μž… μ„€λͺ… 주둜 ν•˜λŠ” 일 λŒ€ν‘œ μ˜ˆμ‹œ
    Dummy 값이 ν•„μš”ν•˜μ§€λ§Œ 아무 역할도 ν•˜μ§€ μ•ŠλŠ” 객체 λ©”μ„œλ“œ μ‹œκ·Έλ‹ˆμ²˜ μ±„μš°κΈ° 용 new User(null)처럼 κ°’λ§Œ 채움
    Fake μ‹€μ œ κ΅¬ν˜„μ— κ°€κΉŒμš°λ‚˜, λ‹¨μˆœν•˜κ±°λ‚˜ in-memory 기반 κ°„λ‹¨ν•œ λŒ€μ²΄ κ΅¬ν˜„ InMemory DB, FakeEmailSender
    Stub κ³ μ •λœ 응닡을 λ¦¬ν„΄ν•˜λŠ” 객체 μƒνƒœ 기반 ν…ŒμŠ€νŠΈ when(repo.findById()).thenReturn()
    Mock ν–‰μœ„ 기반, 호좜 μ—¬λΆ€λ‚˜ μˆœμ„œ 검증이 κ°€λŠ₯ν•œ 객체 ν–‰μœ„ 기반 ν…ŒμŠ€νŠΈ verify(repo).save()
    Spy μ‹€μ œ 객체λ₯Ό κ°μ‹Έλ©΄μ„œ, λΆ€λΆ„μ μœΌλ‘œ mock κ°€λŠ₯ μ‹€μ œ λ™μž‘ + 호좜 κ°μ‹œ spy(new UserService(...))

    1. 🐣 Dummy

    • κ°€μž₯ λ‹¨μˆœν•œ ν˜•νƒœ.
    • 아무 일도 ν•˜μ§€ μ•Šκ³ , κ°’λ§Œ μ±„μš°λŠ” μš©λ„.
    • ν…ŒμŠ€νŠΈμ— 직접적 의미 μ—†μŒ. 없어도 ν…ŒμŠ€νŠΈ 톡과 κ°€λŠ₯.
    User dummyUser = new User(null); // μƒμ„±μž λ§€κ°œλ³€μˆ˜ λ§žμΆ”λ €κ³  λ„£λŠ” μš©λ„
    

    2. πŸ§ͺ Stub

    • ν˜ΈμΆœν•˜λ©΄ μ •ν•΄μ§„ 값을 리턴함.
    • λ™μž‘ μžμ²΄λŠ” λ‹¨μˆœν•˜κ³  검증 λ‘œμ§μ€ μ—†μŒ.
    • μƒνƒœ 기반 ν…ŒμŠ€νŠΈμ— μ‚¬μš©λ¨.
    when(userRepository.findById(1L)).thenReturn(Optional.of(new User("Alice")));
    

    3. πŸ€– Mock

    • Stub처럼 리턴값을 쀄 수 μžˆμ§€λ§Œ, μΆ”κ°€λ‘œ 호좜 여뢀도 검증함.
    • ν…ŒμŠ€νŠΈμ˜ **ν–‰μœ„ 검증(Behavior Verification)**에 초점.
    verify(userRepository, times(1)).save(any());
    

    4. πŸ•΅οΈ Spy

    • μ‹€μ œ 객체λ₯Ό κ°μ‹Έλ©΄μ„œ, ν•„μš”ν•œ λΆ€λΆ„λ§Œ mock 처리 κ°€λŠ₯.
    • 일뢀 λ©”μ„œλ“œλŠ” μ§„μ§œ μ‹€ν–‰, μΌλΆ€λŠ” stub/mock κ°€λŠ₯.
    • μ‚¬μš© μ‹œ 쑰심: μ§„μ§œ μ˜μ‘΄μ„±μ΄ λ”°λΌμ˜¬ 수 있음.
    UserService spyService = spy(new UserService(realRepository));
    doReturn("fakeName").when(spyService).getUserName();
    

    5. 🧩 Fake

    • μ§„μ§œ κ΅¬ν˜„μ²΄λŠ” μ•„λ‹ˆμ§€λ§Œ, μ‹€μ œλ‘œ λ™μž‘ν•˜λŠ” κ°„λ‹¨ν•œ κ΅¬ν˜„.
    • ν…ŒμŠ€νŠΈμš©μœΌλ‘œ κ°€λ³κ²Œ λ§Œλ“  μ§„μ§œ λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ 흉내낸 것.
    • 예: InMemory DB, ν…ŒμŠ€νŠΈμš© λ©”μ‹œμ§€ 큐 λ“±
    public class InMemoryUserRepository implements UserRepository {
        private Map<Long, User> db = new HashMap<>();
        public Optional<User> findById(Long id) { return Optional.ofNullable(db.get(id)); }
    }
    

    🎯 μ–΄λ–€ κ±Έ μ–Έμ œ 써야 ν• κΉŒ?

    ν…ŒμŠ€νŠΈ λͺ©μ  μ ν•©ν•œ 더블
    νŒŒλΌλ―Έν„° μ±„μš°κΈ°λ§Œ ν•˜λ©΄ 됨 Dummy
    κ³ μ •λœ κ°’ λ¦¬ν„΄λ§Œ ν•„μš” Stub
    호좜 μ—¬λΆ€/횟수 검증 Mock
    μ‹€μ œ 객체 + 일뢀 mocking Spy
    μ‹€μ œ κ΅¬ν˜„ λΉ„μŠ·ν•œ λ™μž‘ ν•„μš” Fake

    Fake Repository μ˜ˆμ‹œ

    Spring ν™˜κ²½μ—μ„œ 자주 μ“°μ΄λŠ” Fake Repository 예제λ₯Ό λ³΄μ—¬λ“œλ¦΄κ²Œμš”.
    λ‹¨μœ„ ν…ŒμŠ€νŠΈμ—μ„œ JPA 같은 μ‹€μ œ DB μ—°κ²° 없이도 λ‘œμ§μ„ κ²€μ¦ν•˜κ³  싢을 λ•Œ μ•„μ£Ό μœ μš©ν•©λ‹ˆλ‹€.

    Created Thu, 03 Apr 2025 15:57:29 +0900
  • MSA(Microservices Architecture)μ—μ„œ trace ID와 span IDλŠ” **λΆ„μ‚° 좔적(distributed tracing)**μ—μ„œ μ‚¬μš©λ˜λŠ” 고유 μ‹λ³„μžλ“€μ΄μ•Ό. μ‹œμŠ€ν…œ μ „μ²΄μ—μ„œ μš”μ²­μ˜ 흐름을 좔적할 수 있게 ν•΄μ£ΌλŠ” 핡심 κ°œλ…μž…λ‹ˆλ‹€.


    1. Trace ID

    • ν•˜λ‚˜μ˜ 전체 μš”μ²­(Request)을 μ‹λ³„ν•˜λŠ” κ³ μœ ν•œ IDμž…λ‹ˆλ‹€.
    • 예: μ‚¬μš©μžκ°€ μ›Ήμ—μ„œ μ–΄λ–€ λ²„νŠΌμ„ ν΄λ¦­ν•΄μ„œ API μš”μ²­μ΄ λ“€μ–΄μ˜€κ³ , κ·Έ μš”μ²­μ΄ μ—¬λŸ¬ 개의 λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€λ₯Ό 거쳐 μ²˜λ¦¬λ˜λŠ” 경우, 이 전체 흐름을 ν•˜λ‚˜μ˜ trace둜 λ΄…λ‹ˆλ‹€.
    • 즉, trace IDλŠ” **“이 μš”μ²­μ΄ μ–΄λ””μ„œ μ‹œμž‘λΌμ„œ μ–΄λ””κΉŒμ§€ κ°”λŠ”κ°€”**λ₯Ό λ‚˜νƒ€λƒ„.

    2. Span ID

    • trace μ•ˆμ—μ„œ **각각의 μž‘μ—… λ‹¨μœ„(μž‘μ€ 호좜 ν•˜λ‚˜ν•˜λ‚˜)**λ₯Ό μ‹λ³„ν•˜λŠ” IDμž…λ‹ˆλ‹€.
    • 예: A μ„œλΉ„μŠ€κ°€ B μ„œλΉ„μŠ€μ™€ C μ„œλΉ„μŠ€λ₯Ό ν˜ΈμΆœν•˜λ©΄, A-B, A-C 각각이 λ³„λ„μ˜ span이 되고, 각각에 λŒ€ν•œ span IDκ°€ μžˆμŠ΅λ‹ˆλ‹€.
    • Span은 μ‹œμž‘ μ‹œκ°„, μ’…λ£Œ μ‹œκ°„, μ–΄λ–€ μž‘μ—…μΈμ§€ λ“± μ„ΈλΆ€ 정보도 ν¬ν•¨λ©λ‹ˆλ‹€.

    ꡬ쑰 μ˜ˆμ‹œ

    [Trace ID: abc123]
    
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚ User Request│──────▢│ API Gateway │───┐
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
                                               β–Ό
                                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                       β”‚ Service A  │───┐
                                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
                                                        β–Ό
                                                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                                β”‚ Service B  β”‚
                                                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    
    • 전체 μš”μ²­μ˜ 흐름이 ν•˜λ‚˜μ˜ Trace ID (abc123)λ₯Ό κ³΅μœ ν•˜κ³ ,
    • 각 μ„œλΉ„μŠ€ κ°„ ν˜ΈμΆœμ€ μ„œλ‘œ λ‹€λ₯Έ Span IDλ₯Ό 가짐.

    μš”μ•½

    ν•­λͺ© μ„€λͺ…
    Trace ID 전체 μš”μ²­ 흐름을 μΆ”μ ν•˜κΈ° μœ„ν•œ 고유 ID
    Span ID Trace λ‚΄μ—μ„œ κ°œλ³„ μž‘μ—…μ„ κ΅¬λΆ„ν•˜λŠ” ID

    첨언

    • μ‹€μ œ MSA κ΅¬ν˜„μ‹œ front endμ—μ„œ api requestμ‹œμ λΆ€ν„° trace id와 span idκ°€ μ±„λ²ˆλ˜κ³ 
    • 예λ₯Ό λ“€μ–΄, bff -> api-gateway -> user-service λ₯Ό 톡해 request κ°€ ν˜λŸ¬κ°„λ‹€λ©΄, 각 μ„œλΉ„μŠ€λŠ” λ™μΌν•œ trace id둜 좔적이 λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.
    Created Wed, 02 Apr 2025 10:50:33 +0900
  • JVM(Java Virtual Machine)μ—μ„œλŠ” λ‚΄λΆ€μ μœΌλ‘œ μ—¬λŸ¬ μ’…λ₯˜μ˜ μŠ€νƒ(stack) 을 μ‚¬μš©ν•©λ‹ˆλ‹€. 각각의 μŠ€νƒμ€ JVM의 μ‹€ν–‰ 및 λ©”λͺ¨λ¦¬ 관리 λ“±μ—μ„œ μ€‘μš”ν•œ 역할을 ν•©λ‹ˆλ‹€. μ£Όμš” μŠ€νƒ μ’…λ₯˜λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:


    🧠 1. Java Virtual Machine Stack (λ˜λŠ” Thread Stack)

    • μ„€λͺ…: 각 μŠ€λ ˆλ“œ(thread) λ§ˆλ‹€ ν•˜λ‚˜μ”© μ‘΄μž¬ν•˜λŠ” μŠ€νƒμž…λ‹ˆλ‹€.
    • μ—­ν• : λ©”μ„œλ“œ 호좜 μ‹œ μƒμ„±λ˜λŠ” μŠ€νƒ ν”„λ ˆμž„(stack frame) 을 μ €μž₯ν•©λ‹ˆλ‹€. 각 ν”„λ ˆμž„μ—λŠ”:
      • μ§€μ—­ λ³€μˆ˜(Local Variables)
      • ν”Όμ—°μ‚°μž μŠ€νƒ(Operand Stack)
      • λ©”μ„œλ“œ λ°˜ν™˜ μ£Όμ†Œ 등이 포함됨
    • μ˜ˆμ™Έ: μŠ€νƒ μ˜€λ²„ν”Œλ‘œμš° λ°œμƒ μ‹œ StackOverflowError λ°œμƒ

    πŸ” 2. Native Method Stack

    • μ„€λͺ…: λ„€μ΄ν‹°λΈŒ λ©”μ„œλ“œ(C둜 κ΅¬ν˜„λœ JNI λ©”μ„œλ“œ λ“±) 호좜 μ‹œ μ‚¬μš©λ˜λŠ” μŠ€νƒμž…λ‹ˆλ‹€.
    • μ—­ν• : C/C++ λ“± JVM μ™ΈλΆ€ μ–Έμ–΄λ‘œ κ΅¬ν˜„λœ λ©”μ„œλ“œμ—μ„œ ν•„μš”ν•œ 데이터λ₯Ό μ €μž₯
    • νŠΉμ΄μ‚¬ν•­: 일뢀 JVM κ΅¬ν˜„μ—μ„œλŠ” Java μŠ€νƒκ³Ό ν†΅ν•©λ˜κΈ°λ„ 함

    πŸ’Ύ 3. Operand Stack (ν”Όμ—°μ‚°μž μŠ€νƒ)

    • μ„€λͺ…: μœ„μ˜ JVM Stack의 각 μŠ€νƒ ν”„λ ˆμž„ 내에 μ‘΄μž¬ν•˜λŠ” μŠ€νƒμž…λ‹ˆλ‹€.
    • μ—­ν• : λ°”μ΄νŠΈμ½”λ“œ λͺ…λ Ήμ–΄κ°€ μ‹€ν–‰ 쀑인 쀑간 μ—°μ‚° κ²°κ³Όλ₯Ό μž„μ‹œλ‘œ μ €μž₯
    • μ˜ˆμ‹œ: iadd, imul 같은 λ°”μ΄νŠΈμ½”λ“œ λͺ…령은 이 μŠ€νƒμ—μ„œ ν”Όμ—°μ‚°μžλ₯Ό κΊΌλ‚΄ 계산

    🧱 4. Call Stack (호좜 μŠ€νƒ)

    • μ„€λͺ…: JVM Stack의 ꡬ쑰적인 츑면을 μ§€μΉ­ν•˜λŠ” μš©μ–΄λ‘œ, λ©”μ„œλ“œ 호좜의 흐름을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
    • μ—­ν• : ν˜„μž¬ μ‹€ν–‰ 쀑인 λ©”μ„œλ“œλΆ€ν„° μ‹œμž‘ν•΄ 호좜된 λ©”μ„œλ“œλ“€μ΄ 차곑차곑 μŒ“μ—¬ 있음
    • νŠΉμ§•: 디버깅 μ‹œ “Stack Trace"둜 확인 κ°€λŠ₯

    μΆ”κ°€λ‘œ JVMμ—λŠ” μŠ€νƒ 이외에도 λ‹€μŒκ³Ό 같은 λ©”λͺ¨λ¦¬ μ˜μ—­μ΄ μžˆμŠ΅λ‹ˆλ‹€:

    Created Tue, 01 Apr 2025 15:44:09 +0900
  • JVM(Java Virtual Machine)μ—μ„œ heap λ©”λͺ¨λ¦¬λŠ” μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ λŸ°νƒ€μž„ μ‹œ λ™μ μœΌλ‘œ μƒμ„±ν•˜λŠ” 객체듀이 μ €μž₯λ˜λŠ” μ˜μ—­μž…λ‹ˆλ‹€. 즉, new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄μ„œ μƒμ„±ν•˜λŠ” λŒ€λΆ€λΆ„μ˜ 객체듀이 이 μ˜μ—­μ— μ €μž₯λ©λ‹ˆλ‹€.


    πŸ“Œ Heap λ©”λͺ¨λ¦¬ ꡬ성

    Heap은 크게 λ‹€μŒ 두 μ˜μ—­μœΌλ‘œ λ‚˜λ‰©λ‹ˆλ‹€:

    • Young Generation (Young Gen): μƒˆλ‘œ μƒμ„±λœ 객체가 μ €μž₯λ˜λŠ” κ³³.
      • Eden: λŒ€λΆ€λΆ„μ˜ μƒˆ 객체가 여기에 생성됨.
      • Survivor: Edenμ—μ„œ 살아남은 객체듀이 이동.
    • Old Generation (Tenured Gen): Young Gen을 거쳐 였래 살아남은 객체듀이 μ΄λ™ν•˜λŠ” 곡간.

    Garbage Collector(GC)λŠ” 이 heap μ˜μ—­μ˜ 객체듀을 주기적으둜 κ²€μ‚¬ν•΄μ„œ 더 이상 μ°Έμ‘°λ˜μ§€ μ•ŠλŠ” κ°μ²΄λŠ” λ©”λͺ¨λ¦¬μ—μ„œ μ œκ±°ν•©λ‹ˆλ‹€.

    Created Tue, 01 Apr 2025 13:59:38 +0900
  • @Cacheable μ–΄λ…Έν…Œμ΄μ…˜μ€ Spring Frameworkμ—μ„œ λ©”μ„œλ“œμ˜ λ°˜ν™˜κ°’μ„ μΊμ‹œμ— μ €μž₯ν•˜μ—¬, 같은 μΈμžκ°€ λ“€μ–΄μ˜¬ 경우 μΊμ‹œλœ 값을 μž¬μ‚¬μš©ν•˜λ„λ‘ ν•˜λŠ” κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€. 즉, λ©”μ„œλ“œλ₯Ό 반볡적으둜 ν˜ΈμΆœν•˜λ”λΌλ„ μ‹€μ œλ‘œλŠ” 처음 ν•œ 번만 μ‹€ν–‰λ˜κ³ , 이후 ν˜ΈμΆœμ€ μΊμ‹œλœ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜κ²Œ λ©λ‹ˆλ‹€.


    πŸ“Œ μ£Όμš” μ—­ν•  μš”μ•½

    • 쀑볡 호좜 λ°©μ§€: λ™μΌν•œ μž…λ ₯값에 λŒ€ν•΄ λ©”μ„œλ“œλ₯Ό 반볡 ν˜ΈμΆœν•˜λ©΄, μΊμ‹œλœ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•΄ μ„±λŠ₯ ν–₯상.
    • κ²°κ³Ό μ €μž₯: λ©”μ„œλ“œ μ‹€ν–‰ κ²°κ³Όλ₯Ό μΊμ‹œμ— μ €μž₯.
    • 쑰건뢀 캐싱: νŠΉμ • 쑰건에 따라 캐싱 μ—¬λΆ€ μ œμ–΄ κ°€λŠ₯.

    βœ… κΈ°λ³Έ μ‚¬μš© μ˜ˆμ‹œ

    @Cacheable("users")
    public User findUserById(Long id) {
        // μ‹€μ œλ‘œλŠ” DBλ‚˜ μ™ΈλΆ€ API 호좜
        return userRepository.findById(id).orElse(null);
    }
    
    • μœ„ λ©”μ„œλ“œλŠ” usersλΌλŠ” μΊμ‹œ μ΄λ¦„μœΌλ‘œ κ²°κ³Όλ₯Ό μ €μž₯ν•©λ‹ˆλ‹€.
    • idκ°€ λ™μΌν•œ 경우, 이후 ν˜ΈμΆœμ€ μΊμ‹œλœ User 객체λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

    πŸ”§ μ£Όμš” 속성

    속성 μ„€λͺ…
    value λ˜λŠ” cacheNames μ‚¬μš©ν•  μΊμ‹œ 이름 μ§€μ •
    key μΊμ‹œ ν‚€λ₯Ό μ§€μ • (SpEL ν‘œν˜„μ‹ μ‚¬μš© κ°€λŠ₯)
    condition 캐싱할 쑰건 μ§€μ • (SpEL)
    unless κ²°κ³Όλ₯Ό μ €μž₯ν•˜μ§€ μ•Šμ„ 쑰건 (SpEL)

    μ˜ˆμ‹œ:

    @Cacheable(value = "books", key = "#isbn", unless = "#result == null")
    public Book findBook(String isbn) {
        return bookRepository.findByIsbn(isbn);
    }
    

    🧠 ν•¨κ»˜ μ•Œμ•„λ‘λ©΄ 쒋은 μ–΄λ…Έν…Œμ΄μ…˜

    • @CachePut : μΊμ‹œλ₯Ό κ°•μ œλ‘œ μ—…λ°μ΄νŠΈν•  λ•Œ μ‚¬μš©
    • @CacheEvict : μΊμ‹œλ₯Ό μ‚­μ œν•  λ•Œ μ‚¬μš©
    • @Caching : μ—¬λŸ¬ μΊμ‹œ μ–΄λ…Έν…Œμ΄μ…˜μ„ ν•¨κ»˜ μ‚¬μš©ν•  λ•Œ

    ν•„μš”ν•˜λ‹€λ©΄ Redisλ‚˜ Caffeine 같은 μΊμ‹œ μŠ€ν† μ–΄μ™€ ν•¨κ»˜ 연동도 κ°€λŠ₯ν•©λ‹ˆλ‹€.

    Created Tue, 01 Apr 2025 11:34:10 +0900