전체 글 410

Spring boot AOP

Springboot AOP AOP - 핵심 기능과 부가기능 애플리케이션 로직은 크게 핵심기능과 부가 기능으로 나눌 수 있다. 핵심기능은 해당 객체가 제공하는 고유의 기능이다. 부가기능은 핵심기능을 보자하기위해 제공되는기능이다.(로구추적기 등등..) 위 기능들이 하나의 객체에 모두 들어있게되면 여러가지 문제점이 발생 한다. 공통로직이 많이 생긴다.(부가기능은 어느 객체에서나 똑같이 작동하기 때문) 로직의 복잡성이 증가한다. 부가기능 적용 클래스가 100개면 100개에 다 추가해야한다. 부가기능 코드가 복잡해진다면 더욱더 헬오픈이다. 부가기능의 수정요구가 들어오면 수정하기위해서 헬이 오픈된다. 소프트웨어 개발에서 변경지점은 하나가 될수 있도록 잘 모듈화 해야한다.이러한 문제를 해결하기위해서 기존에 OOP의 ..

Springboot 2023.08.14

Spring Data REST

Spring Data Rest RESTFul 웹서비스는 HTTP Method를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미합니다. 기존에 Spring web을 사용하면 @RestController로 컨트롤러를 작성해서 사용해야하지만 Spring Data REST를 사용하면 별도의 컨트롤러없이 Entity와 Repository인터페이스를 보고 분석해서 자동으로 RESTful API를 제공해 줍니다 (짱좋음) 그리고 Spring Data REST는 Spring HATEOAS와 Spring Data JPA의 기능을 자동으로 결합합니다. Spring HATEOAS? Spring HATEOAS는 서버에서 클라이언트로 응답 리소스를 보낼 때 link로 사용가능한 URI를 같이 전달하고 클..

Springboot 2023.08.14

@Aspect Springboot AOP 시작

@Aspect AOP @Aspect 프록시 스프링 애플리케이션에 프록시를 적용하려면 포인트컷과 어드바이스로 구성되어 있는 어드바이저를 만들어서 스프링빈으로 등록하면된다. 그러면 나머지는 아ㅠ서 배운 자동 프록시 생성기가 모두 자동으로 처리해준다. 자동 프록시 생성기는 스프링 빈으로 등록된 어드바이저들을 찾고 스프링 빈들에 자동으로 프록시를 적용해준다. 스프링은 @Aspect 어노테이션으로 매우 편리하게 포인트컷과 어드바이스로 구서오디어 있는 어드바이저 생성 기능을 지원한다. //어드바이저 @Around("execution(* hello.proxy.app..*(..))")//포인트컷 public Object execute(ProceedingJoinPoint joinPoint) throws Throwable..

Springboot 2023.08.14

빈 후처리기

빈후처리기 @Bean이나 컨포넌트 스캔으로 스프링빈을 등록하면, 스프링은 대상객체를 생성하고 스프링 컨테이너 내부의 빈 저장소에 등록을 한다. 그리고 이후에는 스프링 컨테이너를 통해 등록한 스프링빈을 조회해서 사용하면 된다. 빈 후처리기 - BeanPostProcesser 스프링이 빈 저장소에 등록할 목적으로 생성한 객체를 빈 저장소에 등록하기 직전에 조작하고 싶다면 빈 후처리기를 사용하면 된다. 빈을 생성한 후에 무언가를 처리하는 용도로 사용한다. 빈 후처리기 기능 객체를 조작할 수도 있고 완전히 다른객체로 바꿔치기 하는것도 가능하다. 빈등록과정 and 빈후처리기 생성: 스프링 빈 대상이 되는 객체를 생성한다. 전달:생성된 객체를 빈 저장소에 등록하기 직전에 빈후처리기에 전달한다 후처리작업: 빈후처리기..

Springboot 2023.08.14

프록시 팩토리

프록시 팩토리(스프링이 지원하는 프록시) 동적 프록시의 문제점 인터페이스가 있는경우에는 JDK동적 프록시를 적용하고 그렇지 않은 경우에 CGLIB를 적용하려면 어떻게 해야할까? 동시에 사용하는 경우에는 중복으로 만들어서 관리해야하나? 특정 조건에 맞을때 프록시 로직을 적용하는 기능도 공통으로 제공되었으면 프록시 팩토리 스프링은 동적 프록시를 통합해서 편리하게 만들어주는 프록시 팩토리 라는 기능을 제공한다. 프록시 팩토리는 인터페이스가 있으면 JDK동적프록시를 사용하고 구체 클래스만 있으면 CGLIB를 지원한다. 클라이언트가 프록시팩토리로 요청을 하면 프록시 팩토리가 상황에 따라서 jdk동적프록시나 CGLIB구체클래스 프록시로 반환해준다. 부가기능을 적용하기위해 각각 중복으로 따로 만들어야 할까? 스프링은..

Springboot 2023.08.14

JDK동적프록시/CGLIB

JDK 동적 프록시 프록시패턴을 적용하기 위해서는 저거용대상의 숫자만큼 많은 프록시 클래스를 만들어야 했다. 프록시의 로직은 같은데 적용 대상만 차이가 있는것이다. 이 문제를 해결해 주는 것이 동적 프록시 기술이다. 동적 프록시 기술을 사용하면 개발자가 직접 프록시 클래스를 만들지 않아도 된다. 이름 그대로 프록시 객체를 동적으로 런타임에 개발자 대신만들어준다. 그리고 동적 프록시에 원하는 실행로직을 지정할 수 있다. JDK동적 프록시는 인터페이스를 기반으로 프록시를 동적으로 만들어준다. 따라서 인터페이스가 필수이다. JDK 동적 프록시 InvocationHandler JDK 동적 프록시에 적용할 로직은 InvocationHandler 인터페이스를 구현해서 작성해야한다. 인수들은 다음과같다 Object ..

Springboot 2023.08.14

java리플렉션

리플랙션 리플렉션이라는 말의 사전적의미는 투영 같은 느낌의 단어입니다. 이 리플렉션을 통해서 어떠한 요청이 온 파라미터값이나 클래스나 객체에있는 정보들을 쏙쏙 빼갈수 있습니다. 자바가 기본으로 제공하는 JDK동적 프록시 기술이나 CGLIB같은 프록시 생성 오픈소스 기술을활용하면 프록시 객체를 동적으로 만들어 낼 수 있다. 리플랙션 기술을 사용하면 클래스나 메서드의 메타정보를 동적으로 획등하고 코드도 동적으로 호출 할 수 있다. 정적인 코드를 리플랙션을 사용해서 Method라는 메타정보로 추상화한후 공통로직을 만들 수 있게 된다. package hello.proxy.jdkdynamic; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test..

Springboot 2023.08.14

탬플릿 메서드 패턴

핵심기능 vs 부가기능 핵심기능 : 해당객체가 제공하는 고유의 기능 부가기능 : 핵심기능을 보조하기 위해 제공되는 기능. 로그추적, 트랜잭션기능등등... 템플릿 메서드 패턴 좋은 설계는 변하는 것과 변하지 않는 것을 분리하는것이다 핵심기능은 변하고 부가기능은 대게 고정돼 있다. 이 둘을 분리해서 모듈화 해야한다. 템플릿 메서드 패턴이 이문제를 해결해 준다. 템플릿 메서드의 구조는 추상 탬플릿안에 로직들을 다 모아놓고 내부 에 변화하는 로직들을 자식 클래스가 오버라이드 해서 구성하는것입니다. 즉 추상클레스 안에 변하지 않는 로직들을을 다 넣어놓고 변하는 로직은 별도로 호출해서 해결하는패턴입니다 public abstract class 추상클레스{ public void ex(){ 부가기능코드~~ 핵심로직코드(..

Springboot 2023.08.14

Springboot/ ThreadLocal

ThreadLocal 쓰래드 로컬을 알고있어야 하는 이유중 하나는 동시성 문제이다. 동시성 문제 동시성 문제? 첫호출작업이 끝나기도 전에 동시에 다발적으로 호출하게되면 로그가 분리되지않고 떡져서 출력된다. 즉 어떠한 작업을 수행하는 스레드의 트랜젝션이 보장이 되지 않는것이다. 이런 동시성 문제는 여러 쓰레드가 같은 인스턴스 필드에 접근해야 하기 때문에 트래픽이 적은 상황에서는 확율상 잘 나타나지않고 트래픽이 점점 많아질수록 자주 발생해야한다. 특히 스프링 빈처럼 싱글톤 객체의 필드를 변경하며 사용할때 이러한 동시성 문제를 조심해야한다 java에서 지역변수에는 동시성문제가 발생하지 않다. 왜냐하면 스레드마다 각각 다른 메모리 영역이 할당한다. 동시성문제가 발생하는곳은 같은 인스턴스필드 (싱글톤 static..

Springboot 2023.08.14

State 와 Props

Props 1. Properties의 줄임말 2. Props는 상속하는 부모 컴포넌트로 부터 자녀 컴포넌트에 데이터 등을 전달하는 방법 3. Props는 읽기 전용으로 자녀 컴포넌트 입장에서는 변하지 않는다. 변하게 하고자 하면 부모컴포넌트에서 state를 변경시켜 줘야한다. ex) A 부모 컴포넌트 state = {a : "a"} B 자식 컨포넌트 a state 필요 this.props.aprops State 1. 부모 컴포넌트에서 자녀컴포넌트로 데이터를 보내는게 아닌 해당 컴포넌트 내부에서 데이터를 전달하려면 State를 사용하면 된다. 2. State는 변경 가능 3. State이 변하면 re-render된다. ex) A 컴포넌트 state = {a : "a"} this.state.a

React 2023.08.13