본문 바로가기

Back-End

(96)
Spring의 @Configuration 스프링을 공부하다 보면 가장 처음 마주치는 어노테이션 중 하나가 @Configuration 입니다.처음엔 "설정 클래스인가 보다" 하고 넘어가기 쉬운데 이 어노테이션이 하는 일과 쓰는 이유를 정확히 이해하면 스프링 프레임워크에 대한 이해가 더 깊어질 수 있을 것 같아 글을 작성합니다. 이번 글에서는 @Configuration의 역할, @Component와의 차이점, 그리고 실제로 언제 왜 써야하는지를 예시와 함께 정리해보겠습니다.@Configuration의 정체@Configurationpublic class AppConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = objectMapper(); ..
@Fetch(EAGER)와 fetch join 차이와 LAZY 로딩의 작동 방식 1. 즉시 로딩의 두 종료우선 즉시 로딩이란?A 엔티티를 로딩할 때, A와 연결된 연관 엔티티 B도 함께 가져오는 것을 의미한다. 즉시 로딩을 구현하는 방법은 JPA에서 2가지로 구분할 수 있다.방법설명예시제어 가능성EAGER어노테이션으로 고정된 즉시 로딩@ManyToOne(fetch = EAGER)매우 제한적fetch joinJPQL 쿼리로 지정된 즉시 로딩JOIN FETCH동적으로 선택 가능 2. EAGER는 고정, fetch join은 선택 가능EAGER는 선언한 시점부터 항상 즉시 로딩된다.즉 우리가 어떤 쿼리를 쓰든 상관없이 해당 연관 엔티티는 무조건 같이 가져오게 된다.@ManyToOne(fetch = FetchType.EAGER)private User user;위처럼 설정해두면 comment..
Spring AOP Proxy - SelfInvocation 문제 [Spring 애플리케이션이 실행되면서 AOP 프록시가 생성되고 동작하는 과정]1. AOP 적용 대상 클래스(OrderService)@Servicepublic class OrderService { public void processOrder() { System.out.println("Processing order..."); completeOrder(); } @Transactional public void completeOrder() { System.out.println("Order completed!"); printTransactionStatus("completeOrder"); } private void printT..
Spring은 어떻게 객체를 관리할까? ✅ Spring에서 @Component와 의존성 주입이 동작하는 원리"Spring에서 객체 생성과 관리, 그리고 의존성 주입은 어떻게 이루어질까?""왜 @Component를 붙이면 자동으로 빈이 등록될까?""Spring AOP 프록시는 언제 적용될까?"Spring을 사용하다 보면 @Component, @Service, @Repository 등의 어노테이션을 붙이면 자동으로 빈(Bean)으로 등록되고 주입되는 것을 볼 수 있습니다.먼저 들어가기 앞서Spring 컨테이너(ApplicationContext)란?Spring에서 객체의 생성과 생명주기를 관리를 담당하는 핵심 요소가 Spring 컨테이너입니다.이 컨테이너는 빈(Bean)을 관리하고, 필요할 때 의존성을 주입하는 역할을 합니다.✔️ Spring에서 ..
Self-Invocation(자기호출) 문제 현재 결제 프로세스를 진행중인데 @Transactional과 @Retryable을 동시에 사용하는 재시도 로직이 있었습니다.하지만 @Transactional과 @Retryable이 적용이 되지 않는 문제가 발생했습니다.Expected Result Actual Result✅ 하지만 기대와 달리 @Retryable이 작동하지 않는 이슈가 발생했습니다.테스트 케이스 작성그래서 저는 총 7가지 테스트 케이스를 만들어 @Transactional 과 @Retryable이 어떻게 동작하고 어디서 수행되지 않는지 확인을 했습니다.@Retryable 단독 테스트(Case 1~3)케이스설명결고Case1@Retryable 이 적용된 메서드 단독 실행성공Case2같은 클래스 내부에서 일반 메서드가 @Retryable 메서드 ..
재고 감소로 보는 동시성 제어 목차초기 셋팅문제 상황문제 해결법synchronizedPessimistic LockOptimistic LockNamed LockRedis1. 초기 셋팅2. 문제 상황단일 스레드가 실행할 때는 정상적으로 테스트가 통과되는 것을 볼 수 있다.하지만 만약에 동시에 100개의 스레드가 재고 수량 감소를 요청하면 어떨까?1️⃣ 동시에 100개의 요청에 대한 테스트 코드를 보면 ExcutorService를 이용해 100개의 요청을 동시에 실행2️⃣ CountDownLatch로 모든 요청이 끝날 때 까지 대기3️⃣ stockService.decrease(1L, 1L);를 100번 실행하여 재고를 100개 감소4️⃣ assertEquals를 이용해 재고가 0인지 검증내 예상 : 예상 재고 수량 = 0개실제 : 88개왜..
람다식과 함수형 인터페이스 람다식과 함수형 인터페이스람다식 : 익명 함수 라고도 불린다. 자바에서는 인터페이스의 익명 클래스를 간략히 표현하는데 사용된다.함수형 인터 페이스람다식 형태로 익명 클래스가 만들어질 수 있는 인터페이스조건 : 추상 메서드가 하나만 있어야 한다.람다식과 1:1 대응이 될 수 있어야 하므로@FunctionalInterface 로 강제반환값도 없고 파라미터도 없을 때@FunctionalInterfacepublic interface Printer { void print(); // void say (); // 둘 이상의 메서드는 불가하다}Printer printer1 = new Printer() { @Override public void print() { System.out..
JMeter를 활용하여 Redis 캐시 테스트 분석 테스트 조건(1)users(동시 접속자 수) : 100Duration(테스트 실행 시간) : 10초Loop Count : 10캐시 되지 않은 상점(storeId = 100)으로 V1(캐시 미적용)과 V2(캐시 적용)을 독립적으로 실행하여 성능 비교V2(캐시 적용)는 한 번의 요청 이후 Redis 캐시에 저장되어 사용됨.결과 비교➡️ V1 (캐시 미적용)➡️ V2 (캐시 적용)요청샘플 수 평군 응답 시간(ms)최소(ms)최대(ms)표준 편차처리량(ThrouhPut)Get Store V1 (No Cache)20006ms3ms63ms2.21ms73.3 req/sec요청샘플 수 평군 응답 시간(ms)최소(ms)최대(ms)표준 편차처리량(ThrouhPut)Get Store V2 (With Redis Cache)2..