https://github.com/seohaem/kotlin-step1 변수선언 1) var 변수 선언 값 변경이 가능하다. var number1 = 10L 2) val 변수 선언 값 변경이 불가능하다. val number2 = 10L 초기화되지 않은 val 변수는 처음 딱 1번만 값 할당이 가능하다. val number5: Long number5 = 2 print(number5) 3) 타입 선언 Long 타입 변수를 선언해보자. var number3: Long = 10L 선언과 동시에 초기화하는 경우에는 타입 선언은 생략 가능하다. var number3 = 10L 초기화하지 않은 선언은 타입을 넣어줘야한다. var number4: Long number4 = 1 print(number4) 4) Primi..
해당 세미나 강의를 보고 정리 - https://tv.kakao.com/channel/3150758/cliplink/391418995 스프링 웹플럭스 스프링 5.0에 새로 등장한 (새로운) 웹 프레임워크 + 리액티브 스택 SpringMVC 이후 15년만에 처음으로 등장한 신규 웹 프레임워크 초기 이름은 스프링 웹 리액티브였고, 웹플럭스로 명칭이 변경되었다. 스프링 웹플럭스 vs MVC Spring WebFlux - 리액티브 스택 Servlet은 사용 방식은 다르지만 Reactive Stack, Servlet Stack 모두 포함되어있다. JPA(블록킹) 등은 Reactive Stack에는 포함되어있지 않다. Reactor (Reactive Library) 라이브러리 : 웹플럭스의 플럭스는 리액터 라이브러..
애그리거트 간 집합 연관 애그리거트 간 1:N, N:1 연관에 대해 알아보자. 이 두 연관은 컬렉션(Collection)을 이용한 연관이다. 카테고리와 상품 간의 연관이 대표적이다. 카테고리 입장에서 한 카테고리에 한 개 이상의 상품이 속할 수 있으니 카테고리와 상품은 1:N 관계이다. 한 상품이 한 카테고리에만 속할 수 있다면 상품과 카테고리 관계는 N:1 관계이다. 애그리거트 간 1:N 관계는 Set과 같은 컬렉션을 이용해서 표현할 수 있다. 예를 들어 다음 코드처럼 Category가 연관된 Product를 값으로 갖는 컬렉션을 필드로 정의할 수 있다. public class Category { private Set products; // 다른 애그리거트에 대한 1:N 연관 ... } 개념적으로 존재..
리포지토리와 애그리거트 애그리거트는 개념상 완전한 한개의 도메인 모델을 표현하므로 객체의 영속성을 처리하는 리포지터리는 애그리거트 단위로 존재한다. Order와 OrderLine을 물리적으로 각각 별도의 DB 테이블에 저장한다고 해서 Order와 OrderLine을 위한 리포지터리를 각각 만들지 않는다. Order가 애그리거트 루트고 OrderLine은 애그리거트에 속하는 구성요소이므로 Order를 위한 리포지토리만 존재한다. 새로운 애그리거트를 만들면 저장소에 애그리거트를 영속화하고 애그리거트를 사용하려면 저장소에서 애그리거트를 읽어야 하므로, 리포지터리는 보통 다음의 두 메서드를 기본으로 제공한다. 이 두 메서드 외에 필요한 다양한 조건으로 애그리거트를 검색하는 메서드나 애그리거트를 삭제하는 메서드를..
애그리거트 애그리거트는 여러 객체로 구성된다. 그렇기 때문에 한 객체만 상태가 정상이면 안되고, 애그리거트에 속한 모든 객체가 정상 상태를 가져야 도메인 규칙을 지킬 수 있다. [예시] 주문 애그리거트를 보자. Order 엔티티 - 총 금액 totalAmounts를 갖고있다. OrderLine 밸류 - 개별 구매 상품의 개수인 quantity와 금액인 price를 갖고있다. 구매할 상품의 개수를 변경하면 한 OrderLine의 quantity를 변경하고 더불어 Order의 totalAmounts도 변경해야한다. 그렇지 않으면 다음 도메인 규칙을 어기고 데이터 일관성이 깨진다. 루트 애그리거트 애그리거트에 속한 모든 객체가 일관성 상태를 유지하려면 애그리거트 전체를 관리할 주체가 필요한데, 이 책임을 지는..
Mono vs Flux 객체 차이 설명 Mono 0 ~ 1 개의 데이터 전달 Reactive Streams 의 Publisher 인터페이스를 구현하는 구현체 Flux 0 ~ N 개의 데이터 전달 Reactive Streams 의 Publisher 인터페이스를 구현하는 구현체- 하나의 데이터를 전달할 때마다 onNext() 이벤트를 발생한다.- Flux 내의 모든 데이터의 전달 처리가 완료되면 onComplete() 이벤트가 발생한다. 'Mono 예제 맛보기' 포스팅 바로가기 https://devfunny.tistory.com/882 Flux 예제 맛보기 Event.java @Data @AllArgsConstructor public class Event { long id; String value; } Mo..
Mono vs Flux 객체 차이 설명 Mono 0 ~ 1 개의 데이터 전달 Reactive Streams 의 Publisher 인터페이스를 구현하는 구현체 Flux 0 ~ N 개의 데이터 전달 Reactive Streams 의 Publisher 인터페이스를 구현하는 구현체 - 하나의 데이터를 전달할 때마다 onNext() 이벤트를 발생한다. - Flux 내의 모든 데이터의 전달 처리가 완료되면 onComplete() 이벤트가 발생한다. 'Flux 예제 맛보기' 포스팅 바로가기 https://devfunny.tistory.com/883 gradle 설정 implementation 'org.springframework.boot:spring-boot-starter-webflux' Mono 예제 맛보기 1) ..
CompletableFuture Java5에 등장한 Future의 단점을 보완한 java8의 클래스다. Future은 get()을 호출하여 작업을 완료하고, get()은 비동기 작업의 결과를 가져올때까지 블로킹 상태가 된다. 여러 Future을 조합할 수 없고, 예외 처리도 불가능하여 이를 보완한 CompletableFuture을 사용하여 비동기 작업을 직접 완료할 수 있다. public class CompletableFuture implements Future, CompletionStage { CompletableFuture는 CompletionStage 인터페이스를 구현한다. CompletionStage는 비동기 연산을 체이닝으로 연속해서 작업들을 중첩시킬 수 있다. public interface C..
애그리거트가 필요한 이유 아래 그림을 보면, 주문이 회원, 상품, 결제와 관련된 것임을 쉽게 알 수 있다. 상위 수준 모델을 개별 객체 단위로 다시 그려보자. 개별 객체 수준에서 모델을 바라보면 상위 수준에서 관계를 파악하기 어렵다. 도메인 객체 모델이 복잡해지면 개별 구성요소 위주로 모델을 이해하게 되고, 전반적인 구조나 큰 수준에서 도메인 간의 관계를 파악하기 어려워진다. 주요 도메인을 파악하기 어렵다는 것은 코드를 변경하고 확장하는 것이 어려워진다는 것을 의미한다. 상위 수준에서 모델이 어떻게 엮여 있는지 알아야 전체 모델을 망가뜨리지 않으면서 추가 요구사항을 모델에 반영할 수 있는데, 세부적인 모델만 이해한 상태로는 코드를 수정하는 것이 꺼려지기 때문에 코드 변경을 최대한 회피하는 쪽으로 요구사항..
비동기 구현 예제 1) Runnable @FunctionalInterface public interface Runnable { public abstract void run(); } 매개변수, 리턴값이 없는 로직 ExecutorService es = Executors.newCachedThreadPool(); /** 별도의 스레드로 실행해보자. */ es.execute(() -> { // 매개변수, 리턴값이 없는 Runnable 구현 try { Thread.sleep(2000); } catch (InterruptedException e) { throw new RuntimeException(e); } log.info("Async"); // return "Hello"; // Runnable 은 리턴이 없다. }..
subscribe()의 과정을 별도 스레드로 수행 1) publisher 생성 Publisher pub = sub -> { sub.onSubscribe(new Subscription() { @Override public void request(long n) { log.debug("request()"); sub.onNext(1); sub.onNext(2); sub.onNext(3); sub.onNext(4); sub.onNext(5); sub.onComplete(); } @Override public void cancel() { } }); }; // pub 2) Subscriber 생성 subOnPub.subscribe(new Subscriber() { @Override public void onSubsc..
Pub/Sub 1) Publisher 생성 Publisher pub = iterPub(Stream.iterate(1, a -> a + 1) .limit(10) .collect(Collectors.toList())); iterPub() private static Publisher iterPub(List iter) { Publisher pub = new Publisher() { // Publisher 의 구현해야하는 메서드 @Override public void subscribe(Subscriber