N° 01 — 목록

'분류 전체보기' (197)

  1. Backend Development/Spring

    Spring - 04. configuration component-scan

    @Configuration이 싱글톤을 보장하는 원리 — CGLIB 프록시와 컴포넌트 스캔@Configurationpublic class AppConfig { @Bean public A a() { return new A(b()); } // b()를 직접 호출 @Bean public B b() { return new B(); }}a()에서 b()를 직접 호출하면 new B()가 두 번 실행될까? — 아니다. @Configuration 클래스는 CGLIB 프록시로 감싸져서, b()를 호출하면 컨테이너에 이미 등록된 bean을 반환한다. 이것이 Spring의 싱글톤 보장 메커니즘이다. (Spring Framework Reference - Java-based Container Config..

    · 댓글
  2. Backend Development/Spring

    Spring - 03. dependency-injection

    @Autowired가 어떤 bean을 선택하는가 — 의존성 주입 패턴과 충돌 해결PaymentGateway 인터페이스를 구현한 bean이 3개다 — StripeGateway, TossGateway, MockGateway. Spring에 @Autowired PaymentGateway gateway를 요청하면 어떤 bean이 주입되는가? Spring은 타입으로 찾고, 이름으로 구분하고, 여전히 모호하면 예외를 던진다.이 글은 세 가지 주입 방식(생성자, 세터, 필드)의 차이, @Qualifier로 모호성을 해결하는 방법, 그리고 @Lazy와 선택적 주입(Optional) 패턴을 풀어간다. (Spring Framework Reference - DI)세 가지 주입 패턴1. 생성자 주입 (권장)// Spring ..

    · 댓글
  3. Backend Development/Spring

    Spring - 02. container bean lifecycle

    Bean이 생성되고 사라지기까지 — 컨테이너와 생명주기의 모든 단계@PostConstruct 메서드 안에서 null을 역참조해 NullPointerException이 났다. 의존성은 분명 @Autowired로 주입해뒀는데. 원인은 — 그 의존 bean의 @PostConstruct가 아직 실행되지 않았기 때문이다. 생성자에서 같은 의존성을 호출했다면 더 일찍, 더 기이하게 터졌을 것이다.이런 문제는 생명주기(lifecycle) 없이는 풀 수 없다. bean이 인스턴스화에서 소멸까지 거치는 단계 — 생성자 → 의존성 주입 → @PostConstruct → BeanPostProcessor 후처리 → 사용 → @PreDestroy — 의 어느 시점에 무엇이 보장되고 무엇이 보장되지 않는지를 알아야, "왜 여기서..

    · 댓글
  4. Backend Development/Spring

    Spring - 01. IoC DI

    new를 직접 부르는 코드가 테스트하기 어려운 이유 — IoC와 DI가 해결하는 문제// Spring 없는 세계public class OrderService { private final PaymentGateway gateway = new StripePaymentGateway(); // 직접 생성 private final MailSender mailer = new SmtpMailSender(); // 직접 생성 public void process(Order order) { gateway.charge(order.getTotal()); mailer.send(order.getCustomerEmail(), "주문 완료"); }}이 코드는 ..

    · 댓글
  5. Backend Development/Java

    Java - 25. classloader jit

    JVM이 new ArrayList()를 처음 실행할 때 일어나는 일 — 클래스 로딩과 JIT 컴파일Java 애플리케이션을 시작하면, 모든 클래스를 한 번에 로드하지 않는다 — 처음 참조되는 순간에 로드한다(lazy loading). 그리고 실행 초기에는 인터프리터로 바이트코드를 한 줄씩 해석하지만, 특정 메서드가 충분히 "hot"해지면 JIT 컴파일러가 네이티브 기계어로 변환한다.이 두 단계 — 클래스 로딩과 JIT 컴파일 — 가 JVM의 성능과 유연성을 동시에 만드는 핵심 메커니즘이다. (JVM Specification §5 - Loading) 이 글은 클래스 로딩의 계층 구조, 바이트코드 검증, JIT 컴파일(C1/C2), 그리고 프로파일링의 작동 원리를 풀어간다.클래스 로딩 — lazy, 계층적, ..

    · 댓글
  6. Backend Development/Java

    Java - 24. jvm gc

    GC 로그에서 "pause"가 200ms인 이유 — JVM 메모리 구조와 가비지 컬렉터 선택프로덕션 서버의 응답 시간이 주기적으로 200ms로 튄다. GC 로그를 보면 GC pause (G1 Evacuation Pause) 187ms가 찍혀 있다. 사용자는 "왜 갑자기 느려지나요?"라고 묻는다. 답은 GC의 stop-the-world — GC가 객체를 회수하는 동안 애플리케이션 스레드가 모두 멈추기 때문이다.서버 응답이 주기적으로 200ms로 튄다. GC 로그를 보면 "GC pause 187ms". 누가 멈추게 하는가? — 가비지 컬렉터가 객체를 청소하는 동안 모든 스레드가 잠시 멈춘다(stop-the-world). 이 글은 왜 멈추는지, G1/ZGC/Shenandoah가 각각 다르게 해결하는지를 풀어간..

    · 댓글