[Spring] 웹 애플리케이션과 영속성 관리
·
Java/Spring
스프링 컨테이너의 기본 전략 스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략 사용 트랜잭션을 시작할 때 영속성 컨텍스트(Persistance Context)를 생성하고 트랜잭션이 끝나면 영속성 컨텍스트를 종료합니다. 핵심 비즈니스 로직을 담당하는 Service 클래스에서 @Transactional 어노테이션을 통해 트랜잭션을 시작하게 되고, 서비스보다 상위 계층에 있는 Layer는 준영속 상태가 됩니다. 준영속 상태가 뭔지 설명드리기 전에 엔티티 생명주기에 대해 간략하게 설명드리겠습니다. 엔티티 생명주기 비영속(new/transient): new 키워드로 객체를 생성만 한 상태 (영속성 컨텍스트에서 관리 X, 1차 캐시, 변경 감지 등의 기능 적용 X) 영속(managed): 영속성 컨텍스트에 의..
[Spring] Filter, Interceptor, ArgumentResolver
·
Java/Spring
비즈니스 로직과 인증 로직을 분리하기 위한 3가지 요소가 있습니다. 이 3가지 요소는 이들은 모두 공통된 인증 로직을 처리합니다. 서비스 규모가 커진다면 보안 체크를 매 요청 때마다 해줘야 합니다. 그래서 이들을 확실하게 구분하고 중복 로직을 없애려고 합니다. Filter, Interceptor, AOP가 있는데, AOP는 매우 방대한 내용이라서, Interceptor와 약간의 차이가 있지만 비슷한 역할을 담당하는ArgumentResolver에 대해서 설명드리겠습니다. 전반적인 흐름도 다음 사진과 같이 Client가 HTTP Request를 보냈을 때, Spring Container 영역 밖에 있는 Filter(Servlet Container 영역)를 거치고 DispatcherServlet에서 해당 요청..
[Spring] Nginx를 이용하여 http(80 Port)로 들어오는 요청을 springboot(8080 Port)로 Redirect 시키기
·
Java/Spring
Nginx의 Reverse Proxy를 활용하여 80포트로 들어오는 요청을 8080포트로 redirect 시키는 실습을 해보려고 합니다. Springboot Root Directory Dockerfile Nginx Install && redirect(80 -> 8080) 설정 brew install nginx mkdir ./nginx && touch nginx/default.conf default.conf (Reverse Proxy 설정) upstream app { server spring-app:8080; # WAS 컨테이너의 이름 } server { listen 80; location / { proxy_pass http://app; 80포트로 들어온 요청을 8080포트로 전달 proxy_set_hea..
[Spring] 계층형 디렉터리, 도메인형 디렉터리 구조
·
Java/Spring
개발을 할 때 디렉터리 구조를 설계하는 방법은 크게 두 가지로 나뉩니다. 계층형 디렉터리, 도메인형 디렉터리 2가지로 구성되는데, 저는 항상 계층형 디렉터리로 설계해 왔습니다. 각각의 디렉터리 구조에는 장, 단점이 있지만, 프로젝트 규모와 팀원들 협업 스타일에 알맞게 설계하는 것이 중요하다고 생각합니다. 이제 차근차근 알아보도록 하겠습니다. 1. 계층형 디렉토리 구조(Layered Directory Structure) 기능 또는 역할에 따라 코드를 계층별로 그룹화하는 방식을 계층형 디렉터리 구조라고 합니다. Web Layer: Client와의 요청을 받아 처리하는 역할 담당을 담당, 컨트롤러(Controller), 필터(Filter) 관련 클래스들이 위치하며, HTTP 요청을 처리하여 비즈니스 로직 수행..
[Spring] 재고 시스템으로 알아보는 동시성 이슈 해결 방법
·
Java/Spring
오늘은 동시성 이슈를 해결하는 과정에 대해서 포스팅하려고 합니다. 재고 시스템을 통해 Application Level에서 문제를 해결하는 방안, Database가 제공하는 Lock을 이용해서 문제를 해결하는 방안, Redis의 Lettuce, Redisson을 활용하는 방안에 대해서 설명드리겠습니다. domain은 간단하게 재고 갯수, version 정보(Optimistic Lock을 적용하기 위함)가 담겨있고, 재고 개수를 감소시키는 decrease 메서드 Stock 클래스로 구성되어 있습니다. service는 domain에서 재고 개수를 감소시키는 decrease 메서드를 호출하는 비즈니스 로직으로 구성되어 있습니다. 이제 multi-thread 환경에서 동시에 100개의 요청을 보냈을 때의 발생하는..
[Spring] 동시성 이슈 및 해결 방안
·
Java/Spring
동시성 두 개 이상의 세션이 공통된 자원에 대해 읽고 쓰는 작업을 하는 경우, 발생할 수 있는 문제 동시성 문제의 2가지 현상 일관성 없는 읽기 세션 2는 동시에 실행되고 있는 세션 1 때문에, 데이터에 접근하는 시점마다 다른 값을 읽게 됩니다. 이러한 문제는 “불변성”, 복사본을 이용하여 해결, 세션2가 최초로 데이터를 조회하는 경우, 해당 데이터를 복사하고 이후에도 계속 사용하는 것입니다. 하지만, JPA에서는 영속성 컨텍스트에 데이터를 1차 캐시에 캐싱하기 때문에, 일관성 없는읽기에 대한 문제는 없습니다. 갱신 손실 세션2에 의해 세션 1의 변경 사항이 무시되는 현상 이러한 동시성 문제를 해결하기 위한 방안 Optimistic Lock(낙관적 락) 자원에 Lock을 걸지 않고 충돌이 발생했을 때, ..
[Spring] Spring AOP
·
Java/Spring
애플리케이션 로직은 큰 틀에서 핵심 기능, 부가 기능 2가지로 나눌 수 있습니다. 핵심 기능은 객체가 제공하는 비즈니스 로직이고, 부가 기능은 핵심 기능과 함께 사용되는 로그 추적 로직, 트랜잭션 기능과 같습니다. 부가 기능은 핵심 기능을 보조하기 위해 사용되는 기능입니다. 부가 기능은 여러 클래스에 걸쳐서 사용되는데 이를 횡단 관심사라고 하며, 하나의 부가기능이 여러 곳에서 동일하게 사용됨을 의미합니다. 하지만, 이러한 중복된 로직을 반복해서 사용하게 된다면 Refactoring에 있어서 많은 번거로움이 발생하게 됩니다. 즉, 이러한 문제점을 해결하기 위해 도입된 기술이 AOP 입니다. AOP가 생기면서 부가 기능을 핵심 기능에서 분리하고 한 곳에서 관리해 줄 수 있게 되었습니다. 그리고 이러한 기술을..
[Spring] Proxy Pattern, Decorator Pattern
·
Java/Spring
Proxy Pattern, Decorator Pattern은 모두 Proxy 기술(클라이언트의 요청을 대신해서 처리해 주는 역할)이 적용됩니다. 이때, 서버와 프록시는 같은 인터페이스를 사용해야 하고, 의존관계를 서버에서 프록시로 변경해도 클라이언트 입장에서는 이러한 사실을 몰라야 합니다(프록시 체인). 앞서 설명드린 DI를 사용하면, 클라이언트의 코드 변경 없이 프록시를 주입할 수 있게 됩니다. 이제 이 둘의 차이와 역할에 대해 설명드리겠습니다. GOF 디자인 패턴에 따라 프록시의 역할은 2가지로 구분됩니다(intent에 의해 구분). 1. Proxy Pattern 권한에 따른 접근 차단, 캐싱, 지연로딩 2. Decorator Pattern 원래 서버가 제공하는 기능에 더해 부가 기능 수행 Proxy..
[Spring] Template Method Pattern, Strategy Pattern, Template Callback Pattern
·
Java/Spring
스프링에서 사용되는 디자인 패턴인 템플릿 메서드 패턴, 전략 패턴, 템플릿 콜백 패턴에 대해 알아보려고 합니다. 이들을 적용하는 이유는 좋은 설계를 위해서입니다. 좋은 설계란 요구 부가 기능(핵심 기능의 보조 기능)을 변경하지 않고 핵심 기능만 변경하게 설계하는 것입니다.(중복된 로직을 변경하지 않고, 변하는 것(비즈니스 로직)만 순수하게 바꾸어주는 것) 우선 좋은 설계에 한 발짝 나아갈 수 있는 템플릿 메서드 패턴에 대해 설명드리고 이와 비슷한 기능을 하고 있지만, 템플릿 메서드 패턴의 단점을 보완할 수 있는 전략 패턴, 전략 패턴에서의 템플릿과 콜백 부분을 강조한 템플릿 콜백 패턴까지 설명드리려고 합니다. GOF 템플릿 메서드 패턴 정의 부모 클래스에서의 템플릿을 정의하고, 일부 변경되는 로직을 자식..
[Spring] DI, IoC 컨테이너
·
Java/Spring
DI, IoC, 컨테이너와 같은 개념들은 Spring Framework의 가장 기본적인 특징입니다. 1. IoC(Inversion of Control, 제어의 역전) 프로그램의 제어 흐름을 프로그래머가 직접적으로 제어하는 것이 아니라, 외부에서 관리하는 것 프로그래머가 객체를 생성할 때, 직접 생성하는 것이 아니라 스프링 컨테이너에서 생성하고 등록된 객체(Bean)를 가져오는 것입니다. 즉, 제어권을 본인이 아닌, 프레임워크(Spring 컨테이너)에게 넘겨줬기 때문에 IoC라는 개념이 도입됐습니다. 2. DI(Dependency Injection, 의존관계 주입) 애플리케이션 실행 시점에 외부에서 실제 구현 객체를 생성하고, 클라이언트에 전달해서 클라이언트와 서버의 실제 의존관계가 연결되는 것 Sprin..