spring
-
Spring 다중 데이터소스 설정 및 트랜잭션 동기화spring/JPA 2021. 5. 23. 17:53
배경 서비스 규모가 작다면 한 애플리케이션에서 보통 한 DB리소스만 사용한다. 어떤 경우는 둘 이상의 DB접근이 필요한 경우도 있고 서로 다른 두 DB서비스를 논리적인 트랜잭션 단위로 묶어 작업을 원자적으로 처리할 필요가 있다. 심지어 DB가 아니더라도 JMS와 같은 서비스 또한 한 트랜잭션 단위로 묶일 필요가 있다. 이번 글에서 위 2가지 경우를 예제로 작성해보고 정리해보자. 1. 한 애플리케이션에서 두개의 DB 연결 2. 두 DB의 작업을 트랜잭션으로 묶어서 처리하기 배경지삭 쌓고 가기 - 로컬 트랜잭션 : 하나의 DB커넥션 안에서 말들어지는 트랜잭션 - 트랜잭션 경계설정 : autoCommit를 false로 설정한 뒤 commit 또는 rollback을 원하는 시점에 호출 - PlatformTran..
-
Spring @Scheduled 사용 및 동작원리spring/core 2021. 5. 19. 16:20
배경 프로젝트에서 멤버가 회원가입하고 로그인하는 과정을 살펴보자. 양식을 입력한 유저는 회원가입 요청을 서버에 하게 된다. 서버는 DB에 회원정보를 저장하는데 그 권한을 PRE로 설정하고 회원 이메일로 인증코드가 포함된 URL을 보낸다. 회원가입한 유저는 본인 이메일로 접속해 이 메일의 URL을 클릭하면 서버가 회원의 권한을 PRE에서 USER로 바꾸고 정상적으로 로그인을 처리할 수 있도록 하게 된다. 서버 내부적으로 유저이메일을 key값으로, 인증코드를 value로 외부 데이터베이스인 redis에 저장하게 된다. 만약 회원가입한 유저가 회원가입만 진행한 후 인증을 제때 처리하지 않으면 어떻게 될까? 레디스에 저장하는 인증코드는 적절한 expire를 갖는 게 맞다. 레디스 저장소가 expire된다면 유저..
-
Spring Interceptor 사용 및 동작 정리spring/core 2021. 5. 14. 10:59
배경 인터셉터가 서블릿에서 어떻게 동작하는지 실습해보자 인터셉터란? 필터, 인터셉터, AOP 모두 어떤 작업을 기준으로 전과 후에 부가기능을 추가해주는 작업을 한다. 필터는 서블릿 작업 전과후, 인터셉터는 핸들러매핑 작업 전과후, AOP는 메서드 처리 전과후에 부가기능을 추가한다. 핸들러매핑은 요청의 URL과 메서드로 구분되니 인터셉터도 비슷한 메카니즘으로 적용할 핸들러매핑을 정할 수 있다는 걸 알 수 있다. 실습 일단 /hello라는 GET 요청에 대해 "middle print!"를 출력해주는 핸들러매핑을 만들었다. 다음으로 HandlerInterceptor를 구현한 HelloInterceptor클래스를 만들고 preHandle()과 postHandle()를 오버라이딩했다. 한가지 특이한 점은 Hell..
-
스프링 DI 방법spring/core 2021. 5. 6. 17:00
배경 처음에 잘 배워서 그런지 스프링의 빈을 생성할 때 사용하는 DI방법에 대해 큰 고민을 하지 않았다. 당연히 롬복 + final + 생성자를 조합한 DI를 활용했다. 당연한 건 없다. 스프링이 제시하는 DI에는 어떤 게 있는지 그리고 왜 당연한 조합을 당연히 썼는지 생각하자. 필드 DI 공식문서에는 아예 소개된 방법도 아니고 인텔리제이는 필드 DI를 쓰지말라고 경고까지 한다. 그래도 필드 DI를 이용해 애플리케이션을 구동해보면 잘된다. 왜 스프링은 필드 DI를 DI방식에서 배제했을까? 장점 코드가 간결하고 의존성을 추가 또는 삭제해도 영향 받는 코드의 양이 적다. (관점에 따라 이건 단점이다-> 단일책임원칙 위배 가능성 up) 단점 우선 가장 큰 단점으로 필드 DI를 이용하면 반드시 스프링 컨테이너를..
-
연관관계 주인 mappedBy 끝내기spring/JPA 2021. 5. 5. 12:49
배경 cascade 옵션을 공부하면서 양방향 연관관계에서 mappedBy개념을 정리했지만 매번 헷갈린다. 예제를 작성하며 완전히 알고 넘어가보자! 개념 RDB는 양방향 연관관계라는 개념이 없다. 단지 한 테이블이 연관테이블의 FK를 가질 뿐이다. FK는 두 테이블 중 한 테이블만 갖고 있다. 반면 JPA는 양방향 연관관계라는 개념이 있다. 이는 레코드를 객체처럼 관리하기 위함이다. RDB는 조인을 이용해 언제든지 다른 테이블을 참조할 수 있지만 상대 객체의 정보가 없는 객체는 연관 객체를 참조할 수 없다는 점을 보완한 것이다. 엔티티를 설계하면서 연관된 두 엔티티를 단방향으로 설계했다면 딱히 문제될 건 없다. 실제로 양방향보다 단방향으로 관계를 갖는 게 자연스러운 경우가 많다. 그럼에도 양방향으로 관계를..
-
JPA 다른 모듈에서 ENTITY 스캔하기spring/JPA 2021. 4. 29. 08:59
배경 마이크로 서비스를 구축하면서 서비스와 서비스를 연결할 때 공통으로 필요한 코드는 모듈로 분리했다. 일명 라이브러리모듈로서 main은 없고 적절히 import만 할 수 있게 만든 것이다. 이러면 공통적으로 사용하는 코드를 한 모듈에서 관리하니 유지보수성이 크게 올라간다. 그렇다면 어떤 코드가 이 라이브러리모듈에 들어가야 할까? 아직 노하우가 많지 않아 정확한 판단을 하기는 어렵지만 작은 경험으로 추측해보았다. 먼저 DTO 같은 경우 큰 논란 없이 라이브러리모듈에 들어가도 될 것 같다. 다음으로 @Entity애노테이션이 붙은 도메인클래스를 생각해봤다. 한 서비스에서 하나의 도메인만 다루더라도 연관관계가 얽혀 있다면 다른 도메인이 필요할 것이다. 결국 완성된 데이터는 한 서비스에서 조립되어 전달되니 도메..
-
Spring Cloud Gatewayspring/cloud 2021. 4. 28. 17:33
배경 클라이언트가 서비스A를 이용하기 위해 요청을 보낼 때 어떻게 처리해야할까? 서비스A의 IP 또는 URL로 HTTP 통신을 하면 된다. 다만, 서비스A가 동일한 서비스를 제공하는 서로 다른 IP를 가진 클러스터로 있다면 어떡할까? 매 요청마다 서비스A의 클러스터 중 어떤 서비스IP를 이용할지 결정하는 알고리즘이 필요할 것이다. 이 방식은 클라이언트와 서버의 의존도를 높이게 되고 각 서버를 마이크로 단위로 보기 힘들게 한다. 이러한 둘 간의 의존도를 낮춰줄 서버가 gateway서버다. 클라이언트는 서비스A의 물리적인 IP에 의존하지 않고 단지 논리적인 서비스A를 게이트웨이에 요청한다. 그럼 실제 어떤 IP로 서비스A를 요청할지 결정하는 건 gateway서버가 되는 것이다! 초간단 설정 의존성 추가 ap..
-
Spring Cloud Config Server 구축spring/cloud 2021. 4. 28. 16:11
배경 애플리케이션에서 설정정보라하면 배포 환경마다 달라질 수 있는 모든 값이다. 12factor에 따르면 이러한 설정정보는 코드에서 분리하여 따로 관리하길 권장하고 있다. 코드에 종속된 설정정보라면 설정정보 변경 시 전체코드 재빌드가 필요하니 유지보수성이 떨어진다. 이를 극복하기 위해 각 프로젝트마다 application.yml을 따로 두어 설정 정보를 관리하면 하드코딩으로 설정정보를 입력하는 것보다 훨씬 유지보수성이 좋아질 것이다. 다만, 이러한 방식은 한 애플리케이션에서 관리해야할 프로젝트가 여럿인 경우에 유지보수성이 떨어지게 된다. spring cloud config를 이용하면 config자체도 하나의 서버로써 설정정보를 동적으로 바꾸고 관리할 수 있다. 또한 각 프로젝트 내에서 설정 정보를 관리하..