Spring & Springboot

jackson-databind, AUTO_DETECT_IS_GETTERS 옵션(is getter)

0. 문제 아래 예제 코드를 보겠습니다. @Getter @AllArgsConstructor @NoArgsConstructor @Builder @Entity public class Book implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column private String title; @Column private int stock; @Column private boolean isSoldOut; // .. 생략 } 간단한 책(Book) Entity 입니다. 설명을 위해 필요한 코드만 작성했습니다. 해당 엔티티에서 주의깊게 볼 부분은 private boolean isSoldOu..

2024.02.14 게시됨

Spring & Springboot

Spring 5.2.X 버전에서 @RequestParam required = true 옵션은 null safety 하지 않다.

2024년 1월 현재 기준으로 개인 프로젝트나 가까운 시일 내에 시작한 프로젝트라면 Springboot 3.X 버전, Spring 6.X 버전을 사용하게 됩니다. 하지만 프로젝트 개발을 한 지 오래된 서비스라면 Spring, Springboot 버전이 꽤 낮을 수 있는데요. 예를 들어, 3년 전인 2021년에 개발을 시작한 프로젝트만 하더라도 당시 Springboot의 최신 버전은 2.3.1.RELEASE 였으며 이 때 호환되는 Spring 버전은 5.2.X 이었습니다. 이번 글에서는 이런 점을 심각하게 고려하지 않고 개발을 하다가 마주친 문제에 대해 정리해보려고 합니다. 바로 예제 코드를 보겠습니다. @GetMapping("/v1/book") public Book getBook(@RequestPara..

2024.01.28 게시됨

Spring & Springboot

Spring RestTemplate 까보기

RestTemplate은 Spring에서 동기적인 HTTP 요청을 수행하기 위해 정말 많이 사용되고 있는 클래스입니다. Spring 5.0부터 소개된 WebClient는 HTTP 요청에 대한 동기, 비동기적인 처리 방식을 모두 제공하는 조금 더 최신의 클라이언트지만, 과거 버전의 스프링 프로젝트 + 전통적인 MVC 패턴 안에서 개발을 시작한 프로젝트라면 RestTemplate이 당연히 더 익숙할 수밖에 없습니다. 그래서 이번 글에서는 RestTemplate에 대한 공식 문서와 여러 레퍼런스를 참고해서 RestTemplate을 어떻게 이해하고 사용해야 하는지에 대한 나름의 정리를 해보고자 합니다. 1. RestTemplate은 Deprecated 되나? 구글에 RestTemplate에 대해 검색해보면 아래..

2024.01.11 게시됨

Spring & Springboot

Spring READ 관련 API에서 @Transactional(readOnly = true)는 필수인가?

Spring에서는 @Transactional(readOnly = true) 옵션을 제공합니다. 실제로 많은 사람들이 쓴 글들을 보면 조회 관련 API에서 @Transactional(readOnly = true) 옵션을 사용하면 성능 상 이점을 얻을 수 있다고 말하는데요. 이번 글에서는 @Transactional(readOnly = true)을 사용할 때 얻을 수 있는 이점에 대해 [1] 실제 소스 코드를 보며 분석해보고, [2] 그렇다면 과연 단점은 없는지에 대해서도 확인해보려고 합니다. 1. @Transactional(readOnly = true) 동작 방식과 성능 상 이점 먼저 Transactional 인터페이스에 기재되어 있는 readOnly() 옵션에 대한 설명을 읽어보겠습니다. 크게 두 가지 포..

2023.11.10 게시됨

Spring & Springboot

장애 전파 대응을 위한 Resilience4j Circuit Breaker 실습

MSA 환경에서 한 서비스에 문제가 생겼을 때 다른 서비스에 영향을 최소화하는 것은 매우 중요합니다. 서로 의존성이 있는 두 서비스 중 한 서비스에서 발생하는 네트워크 지연 장애, 캐시 노드 장애, 내부 로직의 장애는 산불처럼 결국 두 서비스 모두에 전파되어 더 큰 장애 상황을 만들기 때문입니다. 1. Resilience4j Resilience4j 라이브러리는 CircuitBreaker, RateLimiter, Retry, Bulkhead, TimeLimiter 등과 같은 다양한 장애 대응 패턴을 구현하고 제공합니다. Circuit Breaker: Circuit Breaker 패턴을 구현하며, 서비스 호출의 장애를 모니터링하고 지정된 임계값 이상의 실패가 발생하면 서비스 호출을 차단하여 더 많은 장애를 ..

2023.11.06 게시됨

Spring & Springboot

JPA 트랜잭션 격리 수준과 낙관적 락 동작을 테스트해보자.

이전에 작성한 글에서는 트랜잭션이 보장해야 할 ACID 개념과 MySQL에서의 트랜잭션 격리 수준에 대해 살펴보고 직접 테스트해봄으로써 각 격리수준에서 어떤 문제가 발생할 수 있는지 살펴봤습니다. MySQL의 트랜잭션 격리 수준 실습해보기 트랜잭션은 ACID라는 아래 네 가지 조건을 만족해야 합니다. 원자성(Atomicity) : 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하든, 모두 실패해야 한다. 일관성(Consistency) studyandwrite.tistory.com 위 글에서 이야기했던 내용을 간단하게 요약해보면 아래와 같이 정리할 수 있을 것 같은데요. [1] READ UNCOMMITTED 격리 수준에서는 커밋하지 않은 데이터를 읽을 수 있어서 DIRTY READ 라..

2023.10.15 게시됨

Spring & Springboot

@SpringBootApplication과 AutoConfiguration 들여다보기

SpringBoot 프로젝트를 생성하면 @SpringBootApplication 어노테이션이 붙은 Application 클래스가 생성됩니다. 그리고 @SpringBootApplication은 크게 세 가지 어노테이션(@SpringBootConfiguration, @EnableAutoConfiguration, @ComponentScan)을 포함하고 있는데요. 이번 글에서는 SpringBoot 애플리케이션의 동작의 가장 시작점에 있는 각 어노테이션이 하는 역할을 살펴보고, SpringBoot의 AutoConfiguration 기능의 동작 원리에 알아보겠습니다. 1. @SpringBootConfiguration @SpringBootConfiguration 어노테이션을 들여다보면 아래처럼 @Configurati..

2023.10.07 게시됨

Spring & Springboot

단위 테스트에서 @InjectMocks, @Mock VS @MockBean 이해하기

1. @SpringBootTest와 @MockBean @SpringBootTest는 Junit 테스트에서 @SpringBootApplication 어노테이션을 찾아 하위의 모든 Bean들을 스캔하여 Spring ApplicationContext를 로딩하는 데 사용됩니다. 그리고 이렇게 로딩된 컨텍스트 아래에서 @Autowired로 간단하게 테스트의 대상이 되는 객체를 주입할 수 있게 됩니다. 한편, @MockBean 역시 SpringBoot에서 제공하는 어노테이션으로, Spring ApplicationContext에서 관리되는 Bean을 대체하기 위해 Mockito와 함께 사용됩니다. 즉, @SpringBootTest를 통해 로드한 빈을 Mock 객체로 주입할 수 있게 만드는 것이죠. 그러면 지금까지 설..

2023.04.15 게시됨

Spring & Springboot

JPA 연관관계 편의 메서드의 위치에 대한 내 생각

1. 문제 JPA에서 연관관계 편의 메서드는 양방향 연관관계를 한 번에 설정하기 위해 작성하는 메서드 입니다. 이 때, 통상적으로 엔티티 A(Many), B(One)가 서로 양방향 관계일 때 연관관계 편의 메서드는 총 3가지 케이스로 작성할 수 있습니다. [1] A에 작성하고, B까지 관리한다. [2] B에 작성하고, A까지 관리한다. [3] A, B 각각에 대해 작성한다. 그런데 여기서 [3]번 방식은 둘 중의 한 곳에서라도 메서드 호출을 빼먹으면 논리적인 문제가 생기고 코드의 관리 측면도 복잡해져서 지양하는 패턴입니다. 그러면 [1], [2] 케이스 중에 어디에 연관관계 편의 메서드를 정의하는 게 좋을까요? 이번 글에서는 이 질문에 대한 제 생각을 기록해보려고 합니다. 2. 단순한 ManyToOne ..

2023.03.15 게시됨

Spring & Springboot

[Spring] @CacheEvict 없이 @Cacheable을 쓸 때 생길 수 있는 문제

1. 문제 캐시의 종류에는 크게 두 가지가 있는데요. 바로 로컬 캐시와 글로벌 캐시입니다. 로컬 캐시는 각 서버마다 존재하는 캐시이고, 글로벌 캐시는 여러 서버가 공유할 수 있는 캐시입니다. 부하 분산을 위해 여러 서버를 가지고 서비스를 운영하고 있다면 아마 글로벌 캐시 전략을 가져가고 있을 것입니다. 이번 글에서는 Springboot + JPA + Redis를 활용해서 기본적인 캐시 사용 전략을 실습해보고, 반드시 주의해야 할 내용 한 가지를 짚어보려고 합니다. 2. 테스트 환경 구축 먼저 캐시를 사용할 때 기본적으로 알아야 할 개념인 @Cacheable과 @CacheEvict가 무엇인지 알아보기 위해 간단한 테스트 환경을 구축해보겠습니다. Redis를 설치하지 않으셨다면 여기에서 설치하실 수 있습니다..

2023.02.22 게시됨