1. Jackson ObjectMapper 설정으로 JSON 역직렬화 비용 줄이기[ 불필요한 JSON 역직렬화 메모리 할당 ]오늘날 애플리케이션에서는 캐시, 메시지 큐, 외부 서버의 API 응답 등의 JSON 문자열을 객체로 만드는 경우가 많다. 예를 들어 쇼핑몰에서 사용자별·월별 주문 목록을 JSON 으로 저장해 두고, 주문 내역 화면을 열 때마다 꺼내 객체로 만든다고 하자. 이때 주문의 데이터 구조는 다음과 같고, 한 달치 주문은 많으면 1인당 150건 정도라고 하자.data class Order( val orderId: String, val productName: String, val price: Long, val orderedAt: LocalDateTime, val is..
1. 도커 이미지 빌드 최적화를 위한 Layered Jar [ 기존 Fat JAR 방식의 문제와 Layered Jar의 등장 ]기존 Fat JAR 방식의 문제점Layered Jar란 스프링 부트 애플리케이션을 위한 Docker 이미지를 만들 수 있도록 도와주는 도구이다. 표준 jar 스펙은 jar 내부에 jar 파일을 가질 수 없다. 하지만 애플리케이션을 개발하다 보면 많은 외부의 프레임워크와 라이브러리를 사용하게 되어 다른 Jar가 필요해진다. 따라서 스프링 부트는 jar 내부에 다른 jar를 가지면서 java -jar로 실행할 수 있는 "fat jar" 형식을 예전부터 지원해 왔다. 이러한 fat jar 내부 구성은 다음과 같다. 이러한 fat jar를 도커 이미지로 만드는 것은 어렵지 않다. 하지..
1. Validation 애노테이션 사용 시에 발생하는 ConstraintDeclarationException 에러[ Validation 애노테이션 사용 시에 발생하는 ConstraintDeclarationException 에러 ]에를 들어 다음과 같은 컨트롤러가 존재한다고 하자. 파라미터로 받는 name은 최소 길이가 10이여야 한다는 유효성 검사를 도와주는 @Length 애노테이션이 붙어 있다. 그리고 이를 추싱화한 TestControllerInterface에는 관련 애노테이션 정보가 존재하지 않는 상황이다. 이러한 상황에서 컨트롤러를 호출하게 되면 어떤 결과가 나올까?import org.hibernate.validator.constraints.Length;import org.springframewo..
1. 스프링 부트의 JAR 파일 처리 방식[ WAR 방식의 한계점과 스프링 부트의 등장 ]이전 포스팅에서 살펴보았듯, 스프링 부트는 컨테이너리스(Containerless) 웹 애플리케이션 아키텍처에 대한 요구와 함께 등장했다. 과거에는 톰캣 같은 웹 애플리케이션 서버(WAS)를 먼저 설치하고, 애플리케이션 코드를 WAR로 빌드한 후, 빌드한 WAR 파일을 WAS로 옮기고(배포) WAS를 실행하는 절차들이 필요했다.하지만 이는 WAS를 서버에 직접 설치해야 하는 번거로움 뿐만 아니라, 개발 환경 설정과 배포 과정의 복잡함 등 많은 단점이 있었다. 따라서 스프링이 “애플리케이션의 설정을 처음부터 끝까지 지원하는 아키텍처를 제공해준다면, 단순히 main 메소드를 호출하는 것 만으로도 애플리케이션의 실행과 ..
1. @Async에서 The bean could not be injected because it is a JDK dynamic proxy 에러 발생 원인 분석하기[ 문제 발생 상황 ]다음과 같이 TestInterface와 이를 구현한 TestService가 있고, TestService를 주입받는 TestController가 있다고 하자.public interface TestInterface { default void hello() { System.out.println("hello"); }}@Service@Slf4jpublic class TestService implements TestInterface { @Async public void gogo() { lo..