일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Spring
- 프로그래머스
- Di
- CKA
- superBuilder
- CI/CD
- IntelliJ
- Vue
- 코딩테스트연습
- dabase
- cd
- java
- hibernate
- SpringMVC
- map
- programmers
- ORM
- 자바
- builder-pattern
- CI
- vuejs
- docker
- 뷰
- 알고리즘
- Oracle
- k8s
- JPA
- 해시맵
- Kubernetes
- DevOps
- Today
- Total
목록개발 (72)
문홍의 공부장
웹 애플리케이션을 개발하다 보면 하나의 클라이언트 요청에 대해 애플리케이션 전반에 걸친 특정 Context를 유지해야 할 필요성이 생긴다. 대표적으로 로깅 정보나 사용자 정보가 있다. 이 때 흔히 사용하는 방안은 ThreadLocal을 활용하는 것이다. 스프링에서 Web Request 가 오게 되면 하나의 쓰레드를 할당해서 해당 작업을 처리하게 된다. 이때 Thread 에 대한 정보를 ThreadLocal 에 저장하게 되면 해당 작업이 끝날 때 까지 모든 상황에서 context 를 유지하고 저장하고 찾아볼 수 있다. ThreadLocal은 쓰레드의 로컬 컨텍스트 변수로 Thread 가 존재하는 한 계속해서 남아 있는 변수이다. 작업 요청이 들어왔을때 하나의 쓰레드가 생성이 되고 작업이 끝나면 쓰레드가 없..
서비스 로직 간의 강결합이 주는 문제점 애플리케이션을 개발하면서, 한 번의 요청에 의해 2가지 이상의 기능을 수행하는 경우가 빈번하게 발생한다. 혹은, 간단하게 시작된 도메인 로직이 서비스가 확장됨에 따라 여러가지 추가 로직이 늘어나는 경우 역시 발생한다. 이러한 상황에서, 다수의 기능을 하나의 메서드에서 코드로 구현하면 기능 간 강결합이 생기게 된다. 강한 결합이 생기면 생길수록 로직을 분리해서 관리하기 어렵고, 특정 기능에 문제가 발생하였을 때 이를 처리하는 로직 역시 섞이게 된다. 클라이언트에서 회원 가입 요청이 발생하였을 때, 아래와 같이 프로세스가 진행된다고 가정해보자. (로직에서 사용한 메서드는 별도 구현이 되어있음을 전제한다.) 회원 등록 가입 축하 메일 발송 @Service @Require..
CompletableFuture 는 기존의 Future 인터페이스의 한계를 보완하기 위해 등장한 클래스이다. Future 인터페이스는 비동기 작업에 대한 결과값을 리턴받기 위해 사용되었으나, 아래와 같은 한계점이 존재한다. 외부에서 완료시킬 수 없고, get(long timeout, TimeUnit unit) 의 timeout 설정으로만 완료 가능 블로킹 코드(get()) 을 통해서만 이후 결과를 처리할 수 있음 여러 Future 를 조합하거나, 예외 처리 할 수 없음 CompletableFuture 는 이름 그대로 외부에서 '완료 가능한' Future 이다. 또한, CompletionStage 인터페이스를 구현하여 작업의 중첩, 완료 후 콜백(Future 간 조합)을 가능하게 하였다. public cl..
애플리케이션을 개발하다 보면, 하나의 테이블에서 조회하는 단순 조회 쿼리 뿐 아니라, 다수의 테이블을 조인하여 값을 조회하는 경우가 매우 빈번하게 발생한다. Querydsl은 결과를 사용자 정의하는 두 가지 방법, 즉 행 기반 변환을 위한 FactoryExpressions와 집계를 위한 ResultTransformer를 제공합니다. Querydsl의 FactoryExpression 구현 기능은 com.mysema.query.types.Projections클래스를 통해 , ResultTransformer 는 com.mysema.query.group.GroupBy를 통해 구현되어 있다. 1. Projection Projection 이란, Querydsl을 이용해 entity전체를 가져오는 것이 아니라 조회 ..
JPA를 사용하다보면 여러가지 상황을 캐치하여 작업을 해야할 경우가 생기곤 한다. 예를 들어, 데이터의 수정/삭제가 발생하였을 시 그 요청 이력을 관리하여야 한다고 가정하자. 이 때 모든 수정/삭제 로직이 끝날 때 이력 관리 테이블에 데이터를 저장하는 로직을 추가하는 것은 매우 비효율적인 일이다. 하이버네이트에서 제공하는 JPA EntityListeners 를 활용하여 엔티티의 생명 주기에 따른 이벤트를 처리할 수 있다. Callback Events PrePersist: persist() 를 호출하기 전, 새로운 엔티티가 영속성 컨텍스트에 관리되기 직전에 호출된다. 식별자 생성 전략을 사용한 경우, 엔티티의 식별자는 아직 존재하지 않는 상태이다. PostPersist: persist()를 호출한 후, f..
공통 응답 형식을 만들 때, 이전에는 컨트롤러 단에서 ResponseDto 를 객체를 이용하여 응답값을 필드에 set 하여 내려주었다. 이 경우, 모든 API 에 ResponseDto 를 직접 적어주어야 한다. 누락되는 케이스가 존재할 수 있고, 공통되는 영역이니 한 곳에서 관리하고자 하는 욕구가 생긴다. 스프링에서 제공하는 ResponseBodyAdvice 인터페이스를 이용하여 공통 응답 형식을 만들 수 있다. public interface ResponseBodyAdvice { boolean supports(MethodParameter returnType, Class> converterType); @Nullable T beforeBodyWrite(@Nullable T body, MethodParamet..
회원 서비스를 개발하면서, 회원을 초대하여 가입시키는 프로세스를 진행하였다. 초대 메일 발송 시에 회원 가입 링크를 보내, 유저가 링크를 클릭하여 나머지 프로세스를 진행할 수 있도록 하는 것이었다. 모든 프로세스가 완료 되어야만 회원 테이블에 저장되도록 구조를 잡았는데, 그렇기 때문에 2가지 문제가 발생했다. 초대할 회원 정보를 모두 메일 링크에 포함하게 되면, 링크가 길어질 뿐 아니라 중요 정보들이 모두 노출되게 된다. 메일 발송 내용을 DB 에 저장하고 저장한 시퀀스를 메일 링크에 포함하게 되면, 시퀀스를 통해 메일 발송 순서를 추정할 수 있게 된다. 위 두 가지 문제점을 해결하기 위해, 메일 발송 시퀀스를 암호화 한 shorten URL 을 생성하여 메일 링크가 길어지는 문제점과, 시퀀스 번호가 그..
금융 도메인이나 정산 시스템을 개발할 때에는, 무엇보다 가장 중요한 것이 숫자의 정합성이다. 돈에 가장 민감한 도메인이기에, 1원 단위의 오차로 인한 개발 건 수정이 잦게 일어났던 경험이 있다. 비용 관련 프로그램을 개발하면서 처음 마주한 것이 BigDecimal 이라는 클래스였다. 자바는 IEEE 754 부동 소수점 방식을 사용하여, 정확한 실수를 저장하지 않고 근사치 값을 저장한다. 때문에 float, double 은 소수점의 정밀도가 정확하지 않아 오차가 발생하게 된다. Type 범위 float 1.4E-45 ~ 3.4028235E38 double 4.9E~324 ~ 1.7976931348623157E308 이과 달리, BigDecimal 은 부동 소수점 방식이 아닌, 정수를 이용해 실수를 표현한다..