Back-End 56

스프링 고급편 - 동적 프록시 기술

핵심 내용만 정리하고  자세한 구현 코드는 올리지 않는다. 스프링 부트 3.3.3 버전 기준 ✔️ 리플렉션 이전까지 프록시를 사용해 로그 추적기 부가 기능을 적용했지만 대상 클래스만큼 프록시 클래스를 만들어야 한다는 단점이 있다.따라서 자바의 기본 제공 기술인 JDK 동적 프록시, CGLIB 같은 프록시 생성 오픈소스 기술을 활용하면 프록시 객체를 동적으로 만들어 낼 수 있다. 하지만 JDK 동적 프록시 생성을 이해하려면 리플렉션을 알아야한다. 리플렉션은 한다미로 메타 데이터 이다. void reflection1() throws Exception { //클래스 정보 Class classHello = Class.forName("hello.proxy.jdkdynamic.ReflectionTest$Hell..

스프링 고급편 - 프록시 패턴과 데코레이터 패턴

✔️ 프록시 패턴  프록시는 대체자 이다.프록시의 주요 기능접근 제어권한에 따른 접근 차단캐싱지연 로딩부가 기능 추가원래 서버가 제공하는 기능에 더해서 부가 기능을 수행예) 요청 값이나, 응답 값을 중간에 변형예) 실행 시간을 측정해서 추가 로그를 남김프록시는 체인 작용이 가능하다.     GOF 디자인 패턴둘다 프록시를 사용하지만 의도에 따라서 프록시 패턴과 데코레이터 패턴으로 구분프록시 패턴 : 접근 제어가 목적데코레이터 패턴 : 새로운 기능 추가가 목적위 그림을 보면클라이언트가 subject에 접근하지만 subject의 구현체인 proxy가 캐시 처리를 하고없다면 target으로 realSubject를 이용해서 처리package hello.proxy.pureproxy.proxy.code;import..

스프링 고급편 - 템플릿 메서드 패턴과 콜백 패턴

✔️ 템플릿 메서드 패턴이전에 만들었던 로그 추적기를 더 향상시켜보자 템플릿 메서드 패턴은 변하지 않는 부분과 변하는 부분을 분리해서 변하지않는 부분을 템플릿(기본 틀)로 정의하고, 변하는 부분은 하위 클래스에서 정의하는 패턴이다.  로그 추적기의 변하지 않는 부분TraceStatus status = null;try { status = trace.begin("message"); //핵심 기능 호출 trace.end(status);} catch (Exception e) { trace.exception(status, e); throw e;}이 부분을 템플릿으로 정의한다. 추상 템플릿 클래스public abstract class AbstractTemplate { private final LogTrace ..

스프링 고급편 - 쓰레드 로컬 ThreadLocal

✔️ 전 시간 필드 동기화에 대하여매번 파라미터로 TraceId를 넘기는 것은 복잡하고 어렵다. 따라서 LogTrace 인터페이스를 만들고 traceHolder를 만들어서 여기에 traceId를 보관하여 동기화 한다.하지만 동시성 이슈가 발생한다. 결론적으로는 쓰레드 로컬을 사용하면 동시성 이슈도 해결된다.   먼저 TraceId를 파라미터로 넘기지 않고 필드 동기화하는 법이다.public interface LogTrace { TraceStatus begin(String message); void end(TraceStatus status); void exception(TraceStatus status, Exception e);} @Slf4jpublic class FieldLogTrace ..

HTTP 상태코드

🧫 상태코드클라이언트가 보낸 요청의 처리를 응답에서 알려주는 기능1xx (Informational) : 요청이 수신되어 처리중2xx (Successful) : 요청 정상 처리3xx (Redirection) : 요청을 완료하면 추가 행동이 필요4xx (Client Error) : 클라이언트 오류 , 서버가 요청을 수행할 수 없음5xx (Server Error) : 서버오류, 서버가 정상 요청을 처리하지 못함모르는 상태코드-> 상위 상태코드로 해석해서 처리ex) 234 ? -> 2xx (Successful)로 처리✖️ 1xx -Informational-거의 사용하지 않음✅ 2xx -Successful-200 OK요청 성공201 Created요청 성공해서 새로운 리소스가 생성됨생성된 리소스는 응답의 Loca..

Back-End/HTTP 2024.08.17

HTTP - 메서드

🖊️ API URI 설계리소스 식별 중점✔️ 리소스의 의미회원CRUD를 예로 들어보자회원 등록, 수정, 조회 자체가 리소스는 아니다.회원 이라는 개념 자체가 리소스가 된다.✔️ 리소스 식별방법회원의 CRUD(기능)를 모두 배제하고회원이라는 리소스만 식별 -> 회원 리소스를 URI에 매핑✔️ 계층 구조를 활용회원 목록 조회 /members회원 조회 /members/{memberId}회원 등록 /members/{memberId}...계층 구조상 상위를 컬렉션으로 보고 복수단어 사용 권장그렇다면 어떻게 구분할까?리소스와 행위를 분리 하는 것이다.📬 GET,POST✔️ GET : 리소스 조회리소스 조회서버에 전달하고 싶은 데이터는 query를 통해서 전달지원하지 않는 서버가 많아서 메시지 바디를 허용하지 않..

Back-End/HTTP 2024.08.17

HTTP 기본

💠HTTP?'Hyper Text Transfer Protocol'➡️ HTML같은 리소스 데이터들을 주고받는 프로토콜모든 것 전송 가능HTML,TEXT, 이미지, 음성, 영상,JSON,XML(API) 등일반적으로 알려진 거의 모든 파일을 전송서버 간 데이터 통신에도 대부분 HTTP를 사용TCP : HTTP/1.1, HTTP/2UDP : HTTP/3HTTP/1.1 주로 사용하지만 구글이나 네이버같은 사이트를 보면 HTTP/2, HTTP/3를 많이 사용한다.해당 사이트에서 어떤 프로토콜을 사용하는 지 보는 방법크롬 브라우저를 기준으로 F12를 눌러 NETWORK상태 창에서Protocol을 보면 나온다 .없을시 저 부분을 우클릭하여 프로토콜을 추가만약 아무것도 안나올 시 Filter부분에 뭔가 있는지 확인?..

Back-End/HTTP 2024.08.17

스프링 고급편 - 로그 추적기

✔️ 로그 추적 [TraceId] 깊이 ->(방향) (호출 메서드) (종료시간) (예외) 로그를 남김으로써 어떤 부분에서 문제가 있는지, 예외가 발생하는지 빠르게 확인이 가능하다. TraceId 와 TraceStatus 클래스를 만들어서 트랜잭션 ID(DB 트랜잭션X) 와 level(깊이), 메세지를 로그로 남긴다. 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; th..

QueryDsl - 핵심만 정리

QueryDsl은 객체 지향적 쿼리 작성 프레임워크이기에 매우 편리하고,컴파일 시점에서 오류를 잡아준다. 또한 가독성이 매우 좋고, 동적 쿼리 작성도 매우 좋다. 의존성 //Querydsl 추가 implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:5.1.0:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api"✔️ JPAQueryFactoryQueryD..

Back-End/QueryDsl 2024.08.14

스프링 데이터 JPA - 분석

✔️ 스프링 JPA 구현체 분석 org.springframework.data.jpa.repository.support.SimpleJpaRepository   @Repository // JPA 예외를 스프링이 추상화한 예외로 변환@Transactional(readOnly = true) // 서비스 계층에서 트랜잭션 시작시 해당 트랜잭션을 전파 받아서 사용public class SimpleJpaRepository ...{ @Transactional public S save(S entity) { if (entityInformation.isNew(entity)) { em.persist(entity); return entity; ..

Back-End/JPA 2024.07.31