Spring 9

Mockito의 Mock, Stub, Spy

Mockito의 Mock, Stub, Spy에 대해 정리한 글입니다. MockMock은 실제 객체처럼 보이지만 내부는 완전히 비어있는 객체입니다.아무런 설정을 하지 않으면 모든 메서드가 기본값(null, false, 0)을 반환합니다.UserRepository mockRepo = mock(UserRepository.class);given(mockRepo.existsByEmail("test@example.com")).willReturn(true);StubMockito에서는 사실 Mock에 given(...).willReturn(...)을 쓰면 Stub처럼 동작합니다.Stub은 단순한 결과를 설정할 때 유용하고 대부분의 단위 테스트에서 자주 사용됩니다.given(orderService.getTotalAmou..

Spring 2025.05.18

트랜잭션 격리 수준

트랜잭션의 ACID 속성 중 격리성이 보장되지 않을 때 발생할 수 있는 문제점들과, 이를 해결하기 위한 트랜잭션 격리 수준을 정리한 글입니다. 격리성여러 트랜잭션이 동시에 수행될 때, 서로의 작업에 간섭하지 않도록 보장하는 성질 격리성이 보장되지 않을 때 발생하는 문제점다른 트랜잭션이 아직 커밋하지 않은 데이터를 읽을 수 있다. : Dirty Read한 트랜잭션에서 같은 데이터를 두 번 읽었는데 값이 달라질 수 있다. : Non-repeatable Read처음엔 없던 데이터가 반복 조회 시 새로 나타날 수 있다. : Phantom Read→ 잘못되고 일관적이지 않는 데이터가 발생한다는 문제점이 있습니다. 트랜잭션 격리 수준RDBMS는 위 문제들을 해결하기 위해 격리 수준을 정의해두었습니다.격리 수준이 높..

Spring 2025.04.20

JPA: N+1 문제

JPA에서 발생하는 N+1 문제의 발생 원인과 해결 방안에 대해 정리한 글입니다. N+1 문제어떤 엔티티를 조회하는 1번의 쿼리와 그 엔티티와 관련된 다른 엔티티들을 각각 조회하는 N번의 쿼리가 추가로 발생하는 현상 발생원인JPA에서 연관 관계를 맺은 엔티티를 LAZY 로딩으로 설정했을 때, 연관된 엔티티에 접근하는 시점에 쿼리가 실행됩니다. 예를 들어 Member 엔티티와 Team 엔티티가 @ManyToOne 관계라고 가정한다면List members = em.createQuery("SELECT m FROM Member m", Member.class).getResultList();for (Member member : members) { System.out.println(member.getTeam()..

Spring 2025.04.20

Spring Boot에서 @RestController로 들어온 HTTP 요청이 처리되어 응답으로 변환되는 전체 과정

Spring Boot에서 @RestController로 들어온 HTTP 요청이 처리되어 응답으로 변환되는 전체 과정을 정리한 글입니다. 클라이언트의 요청을 디스패처 서블릿이 받음요청 정보를 통해 요청을 수행할 컨트롤러를 찾음핸들러 어댑터로 요청을 넘김요청을 받은 핸들러 어댑터가 컨트롤러로 요청을 넘김비즈니스 로직 처리컨트롤러가 반환값을 반환핸들러 어댑터가 반환값을 처리응답 처리기인 returnValueHandler가 후처리ResponseEntity를 반환하면 HttpEntityMethodProcessor가 MessageConverter를 사용해 응답 객체를 직렬화하고 응답 상태를 설정.서버의 응답을 클라이언트로 반환

Spring 2025.04.06

웹 API의 발전 과정: SOAP에서 REST로의 전환

웹 API의 발전 과정에서 SOAP(Simple Object Access Protocol)에서 REST(Representational State Transfer)로 전환된 이유는 복잡성, 유연성, 확장성, 성능 등 여러 측면에서 REST가 더 많은 장점을 제공했기 때문입니다. SOAP에서 REST로 전환된 이유와 각각의 장단점을 정리한 글입니다.SOAP에서 REST로 전환된 이유복잡한 구조 vs. 단순한 구조SOAP는 XML 기반의 메시지 포맷과 WSDL, Schema 등 여러 가지를 필요로 하며 구조가 복잡합니다.REST는 HTTP 기반의 간단한 URL 요청과 JSON 응답으로 상대적으로 가볍고 구현이 쉽습니다.무겁고 느린 통신 vs. 가볍고 빠른 통신SOAP는 XML을 사용하여 데이터가 크고, 파싱 ..

Spring 2025.04.06

Spring MVC: 클라이언트 요청 처리 흐름

Spring MVC에서 클라이언트 요청 처리 흐름을 정리한 글입니다. 전반적인 흐름 요약더보기1. 사용자 요청2. DispatcherServlet 수신3. HandlerMapping 조회하여 적절한 컨트롤러 탐색4. HandlerAdapter 통해 실제 핸들러 호출5. 컨트롤러 메서드 실행6. 반환 타입에 따라 분기   - @Controller → ViewResolver → HTML   - @RestController → HttpMessageConverter → JSON7. 최종 응답 반환 1. 사용자 요청사용자가 웹 브라우저 주소창에 http://어쩌구저쩌구.com을 입력합니다. 이 요청은 이 도메인을 가지고 있는 서버로 갑니다. 가면 문지기가 하나 서있습니다.2. DispatcherServlet 수신..

Spring 2025.03.25

스프링 AOP

Spring에서 AOP(Aspect Oriented Programming)이 필요한 이유와 이를 활용한 실제 애플리케이션 개발 사례를 정리한 글입니다. AOP(Aspect Oriented Programming)더보기프로그램의 핵심 기능과 부가 기능(공통 관심사)을 분리하여 모듈화하는 프로그래밍 패러다임이다.핵심 로직(비즈니스 로직)과 공통 관심사(로깅, 보안, 트랜잭션 등)를 분리해서 코드의 중복을 줄이고, 유지보수를 쉽게 하기 위해서 필요합니다. 예시 비즈니스 로직: OrderService.placeOrder()공통 관심사: 메서드 실행 전/후 로그 출력AOP 적용 전@Servicepublic class OrderService { public void placeOrder() { System..

Spring 2025.03.25

Spring Boot에서 사용되는 Bean 등록 방법

Spring Boot에서 사용되는 Bean 등록 방법을 간단히 정리한 글입니다. 1.  @Component 계열 어노테이션 사용@Service // 또는 @Component, @Repository, @Controller 등public class MyServiceImpl implements MyService { public void doSomething() { System.out.println("서비스 로직 실행"); }}장점간단하고 직관적입니다.역할 구분으로 가독성이 좋습니다.스프링 부트의 자동 구성(@ComponentScan) 덕분에 빠르게 적용 가능합니다.단점스캔 범위 밖이면 등록되지 않습니다.등록 조건, 순서, 제어 등의 유연성이 부족합니다. 2.  @Configuratio..

Spring 2025.03.23

Spring Framework 탄생 배경

Spring Framework의 탄생 배경을 정리한 글입니다. EJB의 한계Spring Framework가 등장하기 전, Java 기반의 엔터프라이즈 애플리케이션 개발에서는 EJB(Enterprise JavaBeans)가 널리 사용되었습니다. 그러나 EJB는 다음과 같은 문제점을 가지고 있어 개발자들에게 큰 부담이 됐습니다. EJB는 핵심 로직 개발뿐만 아니라 환경 설정과 복잡한 XML 설정 파일 관리에 시간을 많이 할애해야 했습니다.EJB 컨테이너는 무겁고 리소스를 많이 소모했습니다.테스트가 어렵습니다.단위 테스트를 진행하려면 EJB 컨테이너가 필요하여 로컬 환경에서의 빠른 테스트가 불가능했습니다.컴포넌트 간 결합도가 높았습니다.위 같은 이유로 어플리케이션 유지보수와 확장이 어려웠습니다. Spring ..

Spring 2025.03.16