[Spring] @ModelAttribute 바인딩 실패와 해결
·
Spring/Spring 기초 지식
@ModelAttribute에서 데이터 바인딩을 위해서 꼭 필요한 메서드가 존재한다. 📌 서론 컨트롤러에서 매게 변수로 dto객체를 받을 때 발생하는 바인딩 오류는 정말 간단하게 해결되지만 자주 발생하는 오류이기도 하다. 그만큼 바인딩에 대해서는 신경 쓰지 않고 알아서 적용되겠지?라는 생각을 가지고 어노테이션을 사용하게 되기 때문인데 수많은 api를 만들어 보게 되지만 바인딩도 @RequestBody인지 @ModelAttribute인지에 따라 그 방식이 다르다. 이번에는 @ModelAttribute를 사용했을 때 나의 실수로 인해 바인딩에 실패했던 내용을 소개하고자 한다. 1. 오류가 발생한 상황 오류가 발생한 코드 분석 아래의 API에 요청을 보냈을 때 바인딩 오류가 발생했다. /** * 마이페이지 수..
Spring 통합테스트: Validation 문제 해결과 깊은 고민
·
Spring/테스트 코드
validation을 사용하여 dto 코드를 작성하고 통합테스트를 진행하던 도중 처음 겪는 문제에 직면했다. 📌 서론 통합테스트에서 "사용자가 잘못된 값을 입력해서 보내면 적절한 예외가 발생한다." 이런 bad 케이스 테스트를 작성하고 실행했다. 이때 예외가 발생해야 테스트가 성공하는데 내가 작성한 테스트에서는 예외가 발생하지 않았다. 그래서 나는 가장 먼저 사용자로부터 데이터를 받아오는 dto객체를 살펴봤다. 나는 dto 객체 내부에 Integer타입을 받는 변수를 선언해 주고 spring-validation의 기능을 적용하여 @Min(0)을 적어줬는데 이렇게 해주면 음수(-) 값이 들어왔을 때 검증에 의해 예외가 발생한다. 이렇게 열심히 세팅한 후 테스트를 진행했다. 그런데 보기 좋게 테스트에 실패했..
[Spring] 톰캣과 스프링: 웹 요청의 라이프사이클 이해하기
·
Spring/Spring 기초 지식
톰캣과 스프링의 웹 요청 처리방법을 이해해 보자 📌 서론 스프링은 복잡한 저수준의 소켓 통신과 스트림 처리를 추상화하여, 개발자가 고수준의 비즈니스 로직에 집중할 수 있도록 설계되었다. 이번 포스트를 통해 스프링 프레임워크와 서블릿 컨테이너(예: Tomcat)가 HTTP 요청을 어떻게 처리하는지, 그리고 이 과정에서 각각의 역할이 무엇인지 상세히 살펴보자 1. 스프링의 http 요청과 관련된 용어 이해하기 서블릿 컨테이너 스프링 애플리케이션은 일반적으로 서블릿 컨테이너(예: Tomcat, Jetty) 내에서 실행된다. 이러한 컨테이너는 저수준의 네트워크 통신을 처리하고, HTTP 요청을 서블릿 API로 변환해 애플리케이션에 전달하는 역할을 한다. DispatcherServlet DispatcherServ..
JPA N+1 문제가 발생하는 상황과 해결방법
·
Spring/JPA
이번 포스트에서는 JPA를 사용할 때 N+1 문제가 발생하는 상황과 3가지 해결방법을 알아보자 📌 서론 JPA에서 너무 많은 SQL 쿼리를 실행하는 것은 성능 문제의 가장 일반적인 원인 중 하나다. 잘못 구현되면, 아주 간단해 보이는 쿼리조차도 데이터베이스에 수십 또는 수백 개의 SQL 쿼리를 발생시킬 수 있다. 우리는 이런 문제를 n+1 쿼리 문제라고 한다. 이번 포스트에서는 이러한 N+1 문제에 대해서 다뤄보고자 한다. 1. N+1 문제가 발생하는 상황 설명 지금부터 N+1 문제가 발생하는 상황을 가정한다. 프로젝트 세팅은 다음과 같다. SpringBoot 3.2 Lombok org.projectlombok:lombok JPA Spring Data JPA DB PostgreSQL Querydsl 5...
스프링에서 느슨한 결합 만들기: 이벤트 기반 아키텍처 적용
·
Spring/Spring 기초 지식
이벤트 기반 아키텍처를 적용해서 느슨한 결합(Coupling)을 만들어 보자 📖 서론 이번 포스트에서는 먼저 결합도가 높은 일반적인 시나리오를 살펴보고, 이를 개선하기 위해 결합도가 높은 코드에 스프링의 이벤트 기반 아키텍처를 적용시켜 보자. 코드를 쉽게 이해하기 위해 자주 사용되는 로그인 프로세스를 예로 들어, 어떻게 결합도를 낮추고 코드의 효율성을 높일 수 있는지 설명하도록 하겠다. 1. 결합도가 높은 login() 메서드 작성하기 결합도가 높은 login() 메서드 코드 분석하기 하단의 login() 메서드에서 처리하는 주관심사와 외부 관심사를 분리시켜 보자. 여기서 주관심사는 사용자의 로그인 과정이며, 외부 관심사(비관심사)는 로그인 후의 추가 작업들(예: 알림 보내기, 타 기기에서의 로그아웃 ..
주니어 개발자의 결합도(Coupling) 이해하기: 스프링에서 결합도 관리하기
·
Spring/Spring 기초 지식
결합도(Coupling)는 (클래스, 모듈, 함수 등) 간의 상호 의존성의 정도를 나타낸다. 📖 서론 개발 분야에서 "결합도(Coupling)"는 소프트웨어의 다양한 구성 요소 간의 상호 의존성의 정도를 나타내는 중요한 개념이다. 이는 소프트웨어 구조의 효율성과 유지보수의 용이성을 결정하는 핵심 요소 중 하나로, 소프트웨어 코드 간의 의존 관계의 정도를 나타낸다. 코드 사이에 강한 결합이 있으면, 한 부분이 바뀌었을 때 다른 부분에도 영향을 많이 준다. 그래서 우리는 보통 낮은 결합도를 유지하려고 한다. 낮은 결합도가 좋은 이유는 몇 가지가 있다. 1. 유지보수의 용이성: 낮은 결합도는 한 컴포넌트의 변경이 다른 컴포넌트에 미치는 영향을 줄여, 유지보수를 용이하게 해 준다. 2. 재사용성의 증가: 각 컴..
[Spring] 테스트: @ParameterizedTest 사용방법
·
Spring/테스트 코드
@ParameterizedTest를 사용하여 테스트 효율성을 높여보자 📌 서론 이번 포스트에서는 @ParameterizedTest를 사용해서 다양한 입력 값에 대한 테스트를 진행하는 방법을 살펴볼 것이다.이 방법으로 테스트 코드를 작성하는 것은 실제로 유효성 검사 같은 것들을 할 때 매우 유용하다. 지금부터 @ParameterizedTest를 사용하지 않을때와 사용할때를 비교해 보면서 왜 이 어노테이션을 통해 입력 값에 대한 테스트를 하는게 좋은지 비교해 보자 1. 테스트하려는 도메인의 비즈니스 로직 이해하기 먼저, 우리가 테스트할 도메인의 비즈니스 로직은 외부에서 validateBasicInfo() 메서드를 호출하면 내부에 담겨있는 변수들을 검증하는 로직이다. 이 메서드는 각 필드가 null이나 빈 문..
[Spring] 테스트 코드: @MockBean/@SpyBean 사용방법
·
Spring/테스트 코드
테스트 코드에서 @MockBean과 @SpyBean을 사용해서 이벤트 리스너 검증을 해보자 📌 서론 이전 포스트에서 열심히 스프링 이벤트 리스너에 대한 테스트 코드를 작성하고 검증했다. 나는 이 2가지 리스너 테스트를 한번에 성공시키고 싶어서 코드를 그대로 합쳐서 테스트를 진행했다. 그런데 테스트에서 오류가 발생했고 이것을 고치는데 생각보다 오랜 시간이 걸렸다. 그 이유는 테스트 코드에 대한 이해가 부족했기 때문인데 특히 @MockBean과 @SpyBean을 함께 사용할 때, 이 두 어노테이션이 어떻게 상호 작용하는지에 대한 이해가 부족했다. 지금부터 이 포스트에서는 두 가지 접근 방식을 비교하면서, 스프링 이벤트 리스너의 반응과 내부 동작을 어떻게 동시에 검증할 수 있는지 내가 겪은 내용을 토대로 설..