분류 전체보기 1341

Ch03. 템플릿 메서드 패턴과 콜백 패턴 - 템플릿 메서드 패턴(적용)

템플릿 메서드 패턴 적용 public abstract class AbstractTemplate { private final LogTrace trace; public AbstractTemplate(LogTrace trace) { this.trace = trace; } public T execute(String message){ TraceStatus status = null; try{ status = trace.begin(message); //로직 호출 T result = call(); trace.end(status); return result; }catch (Exception e){ trace.exception(status, e); throw e; } } protected abstract T call();..

Ch03. 템플릿 메서드 패턴과 콜백 패턴 - 템플릿 메서드 패턴(예제)

Test 작성 @Slf4j public class TemplateMethodTest { @Test public void templateMethod(){ logic1(); logic2(); } private void logic1(){ long startTime = System.currentTimeMillis(); //비지니스 로직 실행 log.info("비지니스 로직1 실행"); //비지니스 로직 종료 long endTime = System.currentTimeMillis(); long resultTime = endTime - startTime; log.info("resultTime = {}", resultTime); } private void logic2(){ long startTime = System...

Ch03. 템플릿 메서드 패턴과 콜백 패턴 - 템플릿 메서드 패턴(시작)

V3 메서드를 실제 운영 중인 애플리케이션에 베포 하려니 개발자들의 반대가 심하다( 로그를 출력해야 하는 부가 기능 코드가 핵심기능보다 훨씬 더 많고 복잡하다) 핵심 기능 vs 부가 기능 핵심 기능은 해당 객체가 제공하는 고유의 기능이다. 예를 들어서 orderService의 핵심 기능은 주문 로직이다. 메서드 단위로 보면 orderService.orderItem()의 핵심 기능은 주문 데이터를 저장하기 위해 리포지토리를 호출하는 orderRepository.save(itemId) 코드가 핵심 기능이다. 부가 기능은 핵심 기능을 보조하기 위해 제공되는 기능이다. 예를 들어서 로그 추적 로직, 트랜잭션 기능이 있다. 이러한 부가 기능은 단독으로 사용되지는 않고, 핵심 기능과 함께 사용된다. 예를 들어서 로..

Ch02. 쓰레드 로컬(ThreadLocal) - ThreadLocal

스레드 로컬은 해당 스레드만 접근할 수 있는 특별한 저장소를 말한다 쉽게 이야기해서 물건 보관 창구를 떠올리면 된다. 여러 사람이 같은 물건 보관 창구를 사용하더라도 창구 직원은 사용자를 인식해서 사용자별로 확실하게 물건을 구분해준다. 사용자 A, 사용자 B 모두 창구 직원을 통해서 물건을 보관하고, 꺼내지만 창구 지원이 사용자에 따라 보관한 물건을 구분해주는 것이다 일반적인 변수 필드 스레드 로컬 자바는 언어 차원에서 스레드 로컬을 지원하기 위한 java.lang.ThreadLocal 클래스를 제공한다. 예제 코드 ThreadLocalService @Slf4j public class ThreadLocalService { private ThreadLocal nameStore = new ThreadLoca..

Ch02. 쓰레드 로컬(ThreadLocal) - 동시성 문제(예제 코드)

Test에서도 롬복을 사용하기 위해 Build.gradle에 추가 dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' //테스트에서 lombok 사용 testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' } FieldServ..

Ch02. 쓰레드 로컬(ThreadLocal) - 필드 동기화

파라미터를 넘기지 않고 문제를 해결해 보자 LogTrace 인터페이스 public interface LogTrace { TraceStatus begin(String message); void end(TraceStatus status); void exception(TraceStatus status, Exception e); } FieldLogTrace @Slf4j public class FieldLogTrace implements LogTrace{ private TraceId traceIdHandler; private static final String START_PREFIX = "-->"; private static final String COMPLETE_PREFIX = "

Ch01. 예제 만들기 - 로그 추적기(3)

파라미터로 동기화 개발 첫 로그에서 사용한 트랜잭션 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 = "

Ch01. 예제 만들기 - 로그 추적기(2)

프로토타입 개발 TraceId.class @Getter public class TraceId { private String id; private int level; public TraceId() { this.id = createId(); this.level = 0; } private TraceId(String id, int level) { this.id = id; this.level = level; } private String createId() { //앞 8자리만 사용 //중복이 될수 있지만 트랜잭션 ID 이기 때문에 상관 X return UUID.randomUUID().toString().substring(0, 8); } private TraceId createNextId(){ return new ..

Ch01. 예제 만들기 - 로그 추적기(1)

요구사항 모든 PUBLIC 메서드의 호출과 응답 정보를 로그로 출력 애플리케이션의 흐름을 변경하면 안 됨 로그를 남긴다고 해서 비즈니스 로직의 동작에 영향을 주면 안 됨 메서드 호출에 걸린 시간 정상 흐름과 예외 흐름 구분 예외 발생 시 예외 정보가 남아야 함 메서드 호출의 깊이 표현 HTTP 요청을 구분 HTTP 요청 단위로 특정 ID를 남겨서 어떤 HTTP 요청에서 시작된 것인지 명확하게 구분이 가능해야 함 트랜잭션 ID (DB 트랜잭션 X), 여기서는 하나의 HTTP 요청이 시작해서 끝날 때 까지를 하나의 트랜잭션이라 함