FrameWork/Spring&Spring-boot
-
Spring Core - 전략 패턴(시작, 예제1, 예제2)FrameWork/Spring&Spring-boot 2024. 3. 7. 10:34
전략 패턴 - 시작 ContextV1Test package com.spring.core.trace.strategy; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @Slf4j public class ContextV1Test { @Test void strategyV0(){ logic1(); logic2(); } private void logic1(){ long startTime = System.currentTimeMillis(); //비지니스 로직 실행 log.info("비지니스 로직1 실행"); //비지니스 로직 종료 long endTime = System.currentTimeMillis(); long resultTime = e..
-
Spring Core - 템플릿 메서드 패턴(예제3, 적용1, 적용2)FrameWork/Spring&Spring-boot 2024. 3. 6. 14:04
템플릿 메서드 패턴 - 예제3 익명 내부 클래스 사용하기 템플릿 메서드 패턴은 SubClassLogic1, SubClassLogic2 처럼 클래스를 계속 만들어야 하는 단점이 잇다. 익명 내부 클래스를 사용하면 이런 단점을 보완할 수 있다. 익명 내부 클래스를 사용하면 객체 인스턴스를 생성하면서 동시에 생성할 클래스를 상속 받은 자식 클래스를 정의할 수 있다. 이 클래스는 SubClassLogic1 처럼 직접 지정하는 이름이 없고 클래스 내부에 선언되는 클래스여서 익명 내부클래스라 한다. /** * 템플릿 메서드 패턴, 익명 내부 클래스 사용 */ @Test void templateMethodV2(){ //익명내부 클래스로 // 객체를 생성하는 동시에 구현할 수 있다. //즉 추상 클래스를 상속 받은 클..
-
Spring Core - 템플릿 메서드 패턴(시작, 예제1, 예제2, 정의)FrameWork/Spring&Spring-boot 2024. 3. 6. 10:38
템플릿 메서드 패턴 - 시작 로그 추적기 도입 전 - V0코드 //OrderControllerV0 코드 @GetMapping("/v0/order") public String createOrder(String itemId){ orderService.orderItem(itemId); return "ok"; } //OrderServiceV0 코드 public void orderItem(String itemId){ orderRepository.save(itemId); } 로그 추적기 도입 후 - V3코드 //OrderControllerV3코드 @GetMapping("/v3/order") public String createOrder(String itemId){ TraceStatus status = null; t..
-
Spring Core - 쓰레드 로컬 동기화(적용, 주의사항)FrameWork/Spring&Spring-boot 2024. 3. 6. 09:12
쓰레드 로컬 동기화(적용) package com.spring.core; import com.spring.core.logTrace.LogTrace; import com.spring.core.logTrace.ThreadLocalLogTrace; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Configration { @Bean public LogTrace logTrace(){ // return new FieldLogTrace(); return new ThreadLocalLogTrace(); } } 동시성 ..
-
Spring Core - 쓰레드 로컬(동시성문제2)FrameWork/Spring&Spring-boot 2024. 3. 5. 13:58
동시성 문제 - 예제 코드 동시성 문제가 어떻게 발생하는지 단순화해서 알아보자 테스트에서도 lombok을 사용하기 위해 다음 코드를 추가하자 build.gradle dependencies{ ... //테스트에서 lombok 사용 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor'org.projectlombok:lombok:' } 이렇게 해야 테스트 코드에서 @Slfj4 같은 어노테이션이 작동한다. FieldService @Slf4j public class FieldService { private String nameStore; public String logic(String name){ // 1. 파라미터 name값, nameStore..
-
Spring Core - 쓰레드 로컬(필드 동기화, 동시성 문제1)FrameWork/Spring&Spring-boot 2024. 3. 4. 14:47
쓰레드 로컬 - 필드 동기화 앞서 로그 추적기를 만들면서 다음 로그를 출력할 때 트랜잭션ID와 level을 동기화 하는 문제가 있었다. 이 문제를 해결하기 위해 TraceId를 파라미터로 넘기도록 구현했다. 이렇게 해서 동기화는 성공했지만, 로그를 출력하는 모든 메서드에 TraceId 파라미터를 추가해야 하는 문제가 발생했다. TraceId를 파라미터로 넘기지 않고 이 문제를 해결할 수 있는 방법은 없을까? 이런 문제를 해결할 목적으로 새로운 로그 추적기를 만들어보자. 향후 다양한 구현체로 변경할 수 있도록 LogTrace 인터페이스를 먼저 만들고, 구현해보자. LogTrace 인터페이스 public interface LogTrace { TraceStatus begin(String message); vo..
-
Spring Core - 로그 추적기(V2 파라미터로 동기화 개발)FrameWork/Spring&Spring-boot 2024. 3. 4. 12:52
V2 파라미터로 동기화 개발 트랜잭션ID와 메서드 호출의 깊이를 표현하는 가장 단순한 방법은 첫 로그에서 사용한 트랜잭션ID와 level을 다음 로그에 넘겨주면 된다. 현재 로그의 상태 정보인 트랜잭션ID와 level은 TraceId에 포함되어 있다. 따라서 TraceId를 다음 로그로 넘겨주면 된다. 이기능을 추가한 HelloTraceV2를 개발해보자. HelloTraceV2 @Slf4j @Component public class HelloTraceV2 { private static final String START_PREFIX = "-->"; private static final String COMPLETE_PREFIX = "
-
Spring Core - 로그 추적기(프로토타입, V1)FrameWork/Spring&Spring-boot 2024. 3. 4. 11:16
로그 추적기 요구사항 모든 PUBLIC 메서드의 호출과 응답 정보를 로그로 출력 애플리케이션의 흐름을 변경하면 안된다. (로그를 남긴다고 해서 비지니스 로직의 동작에 영향을 주면 안된다.) 메서드 호출에 걸린 시간 정상 흐름과 예외 흐름 구분 예외 발생시 예외 정보가 남아야 한다. 메서드 호출의 깊이 표현 HTTP 요청을 구분 HTTP 요청 단위로 특정 ID를 남겨서 어떤 HTTP 요청에서 시작된 것인지 명확하게 구분이 가능해야한다. 트랜잭션 ID(DB 트랜잭션 X), 이때 의 트랜잭션으 HTTP요청이 시작해서 끝날 때 까지를 하나의 트랜잭션이라고 한다. 프로토타입 개발 애플리케이션의 모든 로직에 직접 로그를 남겨도 되지만, 그것보다는 더 효율적인 개발 방법이 필요하다. 특히 트랜잭션ID와 깊이를 표현하..