[Advanced-5] 동적 프록시 기술
·
Spring/Core
1. 리플렉션1.1. 리플렉션의 필요성 지금까지 프록시를 사용해서 기존 코드를 변경하지 않고, 로그 추적기라는 부가 기능을 적용할 수 있었다. 그러나 문제는 대상 클래스 수 만큼 로그 추적을 위한 프록시 클래스를 만들어야 한다는 점이다. 로그 추적을 위한 프록시 클래스들의 소스코드는 거의 같은 모양을 하고 있다. 자바가 기본으로 제공하는 JDK 동적 프록시 기술이나 CGLIB 같은 프록시 생성 오픈소스 기술을 활용하면 프록시 객체를 동적으로 만들어낼 수 있다. 쉽게 이야기해서 프록시 클래스를 지금처럼 계속 만들지 않아도 된다는 것이다. 프록시를 적용할 코드를 하나만 만들어두고 동적 프록시 기술을 사용해서 프록시 객체를 찍어내면 된다. JDK 동적 프록시를 이해하기 위해서는 먼저 자바의 리플렉션 기술을..
[Advanced-4] 프록시 패턴과 데코레이터 패턴
·
Spring/Core
1. 프로젝트 생성이전 프로젝트를 일부 수정해서 proxy-start 라는 프로젝트에 넣어두었다.1.1. 프로젝트 설정 순서proxy-start의 폴더 이름을 proxy로 변경하자.프로젝트 임포트File → Open 해당 프로젝트의 build.gradle을 선택하자.그 다음에 선택창이 뜨는데, Open as Project를 선택하자.동작 확인기본 메인 클래스 실행(ProxyApplication())http://localhost:8080 호출해서 Whitelabel Error Page가 나오면 정상 동작2. 예제 프로젝트 만들기2.1. 예제 프로젝트 만들기 v1예제는 크게 3가지 상황으로 만든다:v1 - 인터페이스와 구현 클래스 - 스프링 빈으로 수동 등록v2 - 인터페이스 없는 구체 클래스 - 스프링 빈..
[Advanced-3] 템플릿 메서드 패턴과 콜백 패턴
·
Spring/Core
1. 템플릿 메서드 패턴 - 시작1.1. 문제 상황 지금까지 로그 추적기를 성공적으로 개발하였다. 요구사항을 만족함은 물론, 파라미터 전송의 불편함을 해결하기 위해 쓰레드 로컬(ThreadLocal)까지 도입하였다. 하지만 실제 프로젝트에 적용하려는 단계에서 개발자들의 강한 반대에 부딪혔다. 가장 큰 이유는 본연의 비즈니스 로직보다 부가적인 로그 코드가 더 비대해졌기 때문이다.1.2. 로그 추적기 도입 전 vs 후 비교1.2.1. 도입 전 - V0 코드 // OrderControllerV0 코드@GetMapping("/v0/request")public String request(String itemId) { orderService.orderItem(itemId); return "ok";}// ..
[Advanced-2] 스레드 로컬 - ThreadLocal
·
Spring/Core
1. 필드 동기화 - 개발 앞서 로그 추적기를 만들면서 다음 로그를 출력할 때 트랜잭션ID와 level을 동기화하는 문제가 있었다. 이 문제를 해결하기 위해 TraceId를 파라미터로 넘기도록 구현했다. 이렇게 해서 동기화는 성공했지만, 로그를 출력하는 모든 메서드에 TraceId 파라미터를 추가해야 하는 문제가 발생했다. TraceId를 파라미터로 넘기지 않고 이 문제를 해결할 수 있는 방법은 없을까? 이런 문제를 해결할 목적으로 새로운 로그 추적기를 만들어보자. 이제 프로토타입 버전이 아닌 정식 버전으로 제대로 개발해보자. 향후 다양한 구현체로 변경할 수 있도록 LogTrace 인터페이스를 먼저 만들고, 구현해보자.1.1. LogTrace 인터페이스package hello.advanced.trace..
[Advanced-1] 예제 만들기
·
Spring/Core
1. 프로젝트 생성1.1. 사전 준비물Java 17 이상 설치IDE: IntelliJ 또는 Eclipse 설치스프링 부트 스타터 사이트를 통해 스프링 프로젝트 생성1.2. 프로젝트 설정start.spring.io에서 다음 설정으로 프로젝트 생성:1.2.1. 프로젝트 선택Project: Gradle - Groovy ProjectLanguage: JavaSpring Boot: 3.x.x1.2.2. Project MetadataGroup: helloArtifact: advancedName: advancedPackage name: hello.advancedPackaging: JarJava: 17 또는 21Dependencies: Spring Web, Lombok1.2.3. 주의사항 - 스프링 부트 3.x 버전 ..
[Basic-8] 빈 생명주기 콜백과 빈 스코프의 활용
·
Spring/Core
데이터베이스 커넥션 풀이나 네트워크 소켓 연결처럼 애플리케이션 시작 시점에 필요한 연결을 미리 해두고, 종료 시점에 이를 안전하게 닫는 작업은 매우 중요하다. 스프링이 제공하는 빈 생명주기 콜백과 다양한 빈 스코프를 통해 객체를 효율적으로 관리하는 방법을 알아본다.1. 빈 생명주기 콜백 (Bean Lifecycle Callbacks)스프링 빈은 객체 생성 → 의존관계 주입이라는 라이프사이클을 가진다. 빈은 의존관계 주입이 모두 완료된 후에야 필요한 데이터를 사용할 수 있는 준비가 완료된다. 따라서 초기화 작업은 반드시 의존관계 주입이 끝난 후 호출되어야 한다.1.1. 스프링 빈의 이벤트 라이프사이클스프링 컨테이너 생성 → 스프링 빈 생성 → 의존관계 주입 → 초기화 콜백 → 사용 → 소멸 전 콜백 → 스..
[Basic-7] 의존관계 자동 주입의 전략과 빈 충돌 해결
·
Spring/Core
스프링은 다양한 의존관계 주입 방법을 지원한다. 하지만 실무에서는 특정 방식을 표준으로 사용하며, 여러 개의 빈이 조회될 때 발생하는 충돌을 우아하게 해결하는 것이 중요하다. 이번 글에서는 주입 방식의 종류와 권장되는 선택지, 그리고 빈 충돌 해결 전략을 알아본다.1. 의존관계 주입의 4가지 방법의존관계 주입은 크게 생성자 주입, 수정자(Setter) 주입, 필드 주입, 일반 메서드 주입으로 나뉜다.생성자 주입: 객체 생성 시점에 딱 한 번만 호출되며, 불변성과 필수 의존관계에 사용된다.수정자(Setter) 주입: 선택적이거나 변경 가능성이 있는 의존관계에 사용된다.필드 주입: 코드가 간결하지만 외부에서 변경이 불가능하여 테스트하기 어렵다는 치명적인 단점이 있다. 실무에서는 사용하지 않는 것을 권장한다...
[Basic-6] 컴포넌트 스캔과 자동 의존관계 주입
·
Spring/Core
스프링 빈이 수십, 수백 개로 늘어나면 일일이 @Bean을 통해 설정 정보에 등록하는 과정이 번거로워진다. 이는 설정 정보의 비대화와 누락 문제로 이어진다. 스프링은 이러한 문제를 해결하기 위해 설정 정보 없이도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔(Component Scan) 기능을 제공한다.1. 컴포넌트 스캔과 @Autowired컴포넌트 스캔을 사용하면 빈 등록뿐만 아니라 의존관계 주입까지 자동화할 수 있다.1.1. @ComponentScan설정 클래스에 @ComponentScan 어노테이션을 붙여준다. 기존의 AppConfig와 달리 내부에는 @Bean으로 등록된 클래스가 하나도 존재하지 않는다.@Configuration@ComponentScan( excludeFilters = @Fil..