Programming/Spring Boot 101

@Conditional 어노테이션의 기능과 확장(@ConditionalOnXxx)

@Conditional 어노테이션의 기능과 확장 '@Conditional' 어노테이션은 Spring 4.0(released on 2013)부터 제공되기 시작했는데요. @Configuration, @Component, @Bean 어노테이션과 함께 사용되며, 이름 그대로 특정 조건을 만족하는지를 구별하는 기능입니다. 직접 사용할 일이 많을 것 같지는 않았지만 spring boot 자동 구성에 중요한 역할을 하는 당, 흥미 있는 기능이라고 생각되어 정리해 보았습니다. 아래 내용에서는 @Conditional 어노테이션을 직접 구현 및 적용하여 조건에 따라 동작하는지 여부를 살펴보고, 스프링 부트에서 확장된 @ConditionalOnXxx 어노테이션 기능을 통해 자동 구성이 실행되는 부분에 대해 간단하게 살펴보겠..

@QueryDelegate 어노테이션으로 QueryDSL where절 간결하게 사용하기

QueryDSL @QueryDelegate 어노테이션 사용해 보기 'QueryDSL'은 정접 타입을 이용해서 SQL 등의 쿼리를 생성해 주는 오픈 소스 프로젝트이며, 이름 그대로 query(데이터 조회)에 특화되어 있습니다. * dsl(Domain Specific Language) 특정 도메인을 적용하는데 특화된 프로그래밍 언어 문자가 아닌 코드로 쿼리를 작성하기 때문에 컴파일 시점에서 문법 오류를 발생할 수 있다는 장점이 있으며, 동적인 쿼리 작성이 편리하고, 쿼리의 제약 조건 등을 메서드 추출을 통해 재사용할 수 있다는 장점이 있는데요. 해당 포스팅은 '@QueryDelegate Annotation을 통해 QueryDSL의 where 조건절을 간결하게 사용하는 방법'에 대해 정리한 내용입니다. 예시 ..

JPA 연관 관계 매핑 - 조인 테이블(@JoinTable) 개념과 적용 방법

Join Column, Join Table 관계형 데이터베이스에서는 정규화를 통해 의미 있는 데이터의 집단으로 테이블이 구성되며, 이렇게 구성된 각 테이블끼리는 연관 관계를 갖게 되는데요. 서로 연관 관계가 있는 데이터가 여러 테이블에 나눠서 저장될 수 있기 때문에 필요한 경우 여러 테이블에서 데이터를 효과적으로 검색하기 위해 조인(join)이 사용되는 것은 필수적입니다. * 정규화란 불필요한 데이터 모델의 중목을 최소화하고, 데이터의 일관성과 유연성을 확보하기 위한 목적으로 테이블을 구조화하는 프로세스입니다. 데이터베이스에서 테이블의 연관 관계를 설계하는 방법은 'Join Column'을 사용하는 방법과 'Join Table'을 사용하는 방법 크게 두 가지로 나뉩니다. 대부분의 경우 외래키(Foreig..

Redisson 분산락을 사용하는 이유와 기본적인 사용 방법

동시성 문제(Concurrency Issue)와 분산락(Distributed Lock) 동일한 자원(data)에 대해 여러 스레드가 동시에 접근하면서 발생하는 '동시성 문제'는 상품의 재고 관리 등, 프로세스의 여러 곳에서 발생할 수 있는데요. 이러한 동시성 문제를 해결하는 방법 중 하나로 '분산락'이 있으며, 아래 내용은 'Redisson을 통한 분산락을 사용하는 방법'에 대한 정리입니다. * 동시성 문제(concurrency issue) - 하나의 스레드가 데이터를 수정 중인 상황에서 다른 스레드에서 수정 전의 데이터를 조회하여 수정함으로써 데이터의 정합성(consistency)이 깨지는 문제를 말합니다. * 분산락(distributed lock) - 경쟁 상황(race condition)에서 하나의..

Spring Boot + PayPal 결제 구현해 보기 (sandbox 테스트 환경)

Spring Boot + PayPal 결제 구현 해당 포스팅은 PayPal 결제 테스트 환경인 PayPal sandbox를 사용하여 Spring Boot 프로젝트에서 PayPal Checkout API를 통한 결제 테스트를 구현해 보며 정리한 내용입니다. 전체 코드가 있는 github 주소는 포스팅 맨 하단에 링크되어 있으니 부족한 내용은 해당 링크를 참고해 주시면 좋을 것 같습니다. (아래 구현된 부분은 전체 api 중 아주 일부분에 해당됩니다.) 결제 테스트에 필요한 부분 테스트에 앞서 필요한 것은 테스트를 위한 'PayPal 계정'이 필요하며, 해당 계정에서 생성한 'REST API apps', 'Sandbox text accounts'가 필요합니다. *** test account의 View/Edi..

RedisHash 사용 시 @Indexed 필드 TTL(timeToLive) 적용 안되는 문제

@RedisHash @Indexed field ttl not working Spring Boot에서 @RedisHash + RedisRepository(CrudRepository를 상속받은)를 통해 인메모리 데이터 저장소 redis를 사용하던 중 @Indexed 어노테이션으로 secondary index를 적용한 필드에 대해 ttl(time to live)이 적용되지 않는 현상이 발생하였습니다. 관련 내용을 찾아보니 github issues에서 'Index cleanup happens on the application side and isn't automatically performed by Redis servers.'라는 내용을 찾을 수 있었는데요. (기본적으로 @RedisHash에서 @Id 어노테이션..

양방향 매핑 순환참조 문제 Cannot call sendError() after the response has been committed

양방향 매핑 순환참조 문제 해결 방법(@JsonIgnore, @JsonManagedReference, @JsonBackReference, @JsonIdentityInfo) "Cannot call sendError() after the response has been committed" //User Entity @NoArgsConstructor @Getter @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column private String name; @OneToMany(mappedBy = "user") private List accounts = new ArrayList..

N+1 문제를 해결하기 위한 FetchJoin, 일반 Join과의 차이점은

부끄럽지만 아직까지 'Fetch Join'을 제대로 쓸 줄 모른다는 사실을 반성하며 정리하는 내용입니다. 1. N+1 문제란? jpa 연관 관계 조회 쿼리에서 자주 만나게 되는 문제로, 연관 관계가 설정된 Entity를 조회할 경우 하위 Entity의 데이터 개수(n) 만큼 조회 쿼리가 추가로 발생하여 데이터를 읽어오는 문제를 이야기합니다. N+1 문제가 발생하는 예시를 살펴보면 다음과 같은데요. 2. JPA 연관 관계 조회 쿼리에서 발생하는 N+1 문제 @Builder @AllArgsConstructor @NoArgsConstructor @Getter @Entity public class Board { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) ..

Spring Security + OAuth2 + JWT 소셜 인증 구현(google, kakao, naver)

스프링 부트 security + oauth2 + jwt 소셜 인증 구현 코드 문득 security, oauth2를 사용한 소셜 인증을 제대로 구현해 본 적이 없다는 생각이 들어 구현하며 정리한 내용입니다. 소셜 인증의 경우 많은 애플리케이션에서 사용되는 기능이기 때문에 내용을 잘 파악해 두면 좋다고 생각되는데요. 기능을 구현하며 oauth에 대한 개념 및 oauth2-client의 내부적인 동작 원리에 대한 부분도 궁금하여 포스팅으로 정리해 보았으며, 하나의 포스팅에 모든 내용을 담기는 사실상 어렵기 때문에 아래 포스팅을 참고하시어 해당 코드를 보면 조금 더 이해하기 쉬울 것으로 생각됩니다. (oauth2에 대한 내용으로 대부분 구성되어 있으며 jwt에 대한 내용도 생략되었습니다. jwt에 관련 내용도 ..

스프링 부트 멀티 모듈 프로젝트 생성(gradle)

Spring Boot Multi-Module Project(Gradle) 지난번 spring boot multi-module project 생성하기(maven)에 이어 이번에는 'gradle'을 사용한 멀티 모듈 프로젝트 생성 방법에 대해서 살펴보겠습니다. multi module project를 적용하는 가장 큰 이유는 하나로 운영하던 서비스가 클라이언트 서비스와 운영 시스템 등, 여러 개로 나뉘는 경우가 발생했을 때 각각의 프로그램에 있는 domain의 동일성을 보장하기 위한 것인데요. 멀티 모듈 프로젝트는 무엇인지, 멀티 모듈 프로젝트를 적용하는 이유와 장점에 대한 내용은 아래 포스팅을 참고해 주시면 좋을 것 같습니다. (maven 빌드툴로 구성된 프로젝트에서 multi module project를 ..