-
스프링부트+JPA 블로그 프로젝트 08 스프링 작동 원리 복습스프링/스프링부트+JPA - 블로그 2021. 9. 1. 15:32
유투버 '데어프로그래밍'님 강의 참조
▲ 전체 흐름
1. 톰켓 시작2. 모든 필터가 메모리에 올라감 → 권한/인증/인코딩 등 걸러야할 것들이 여기서 걸러 짐3. 디스패처가 메모리에 올라감 → 사용자가 요청하는 URL주소를 디스패처가 확인하여 컨트롤러로 뿌림4. 컨트롤러→서비스→JPA레파지토리→영속성 컨텍스트가 차례대로 메모리에 뜸
(요청에 따라 새로운 C/S/R/C가 뜨게 됨, 하지만 요청(REQUEST)이 와야 메모리에 뜸. 요청없이는 일단 대기 상태)
5. DataSource하나는 메모리에 뜸 (DS는 DB와 연결되어있음)6. ViewResolver/Intercepter도 메모리에 뜸☞ 로그인 요청시를 예로 보자
1. 사용자가 로그인 요청(REQUEST)
'http://localhost:8000/login' 주소로 'POST' 요청 함 → HTTP BODY에 데이터가 담겨서 옴 (username/password)2. 톰켓→필터→디스패처 작동
3. 디스패처가 컨트롤러중 이 URL주소+PostMapping을 가진 컨트롤러를 메모리에 띄움
4. 컨트롤러는 받으면서 username/password를 같이 받음 (컨트롤러는 함수+파리미터를 만들어서 데이터를 '받는 역할'만 함)
5. 컨트롤러는 이 데이터를 이제 서비스에게 넘기면서 login()을 요청함
6. 서비스에서 login() 시작 → login()시에 데이터(username/password)에대한 select()질의를 해야하므로 JPA레퍼지토리에게 DB와의 질의를 요청함 (select를 DB에서 해줘)
7. JPA레퍼지토리는 확인을 위해서 함수를 요청함 (쿼리네이밍='SELECT*FROM user WHERE ....')
8. 이 함수요청과 관련된 요청이 영속성 컨텍스트에 있는지 1차 확인 → 제일 처음에는 없으니 DS로 요청 → DS가 DB로 질의
9. DS가 질의된 결과를 JPA레퍼지토리로 돌려줌과 동시에 영속성 컨텍스트에 'USER-OBJECT'형태로 남게 됨
10. JPA레퍼지토리는 다시 SERVICE에게 질의응답결과를 돌려줌 → 서비스는 그 결과값이 있는지 아니면 없는지(NULL)에 따라 login()을 시키거나 오류를 띄우고 컨트롤러에 알려주면서 세션에 질의응답이 된 USER값이 등록 됨
11. 컨트롤러는 서비스에서 넘어온 결과가 정상이니 로그인처리가 되고 "/" 이 주소 이하의 페이지를 띄움
* 이때 컨트롤러의 종류가 중요함 → @RestController 이면 데이터를 받는 용, @Controller이면 html페이지를 만들어서 사용자에게 응답하는 용
12. 단순 페이지(템플릿)를 띄우는 컨트롤러가 발동이 되면 ViewResolver가 작동하게 됨, 즉 @Controller일때는 항상 ViewResolver가 작동 함13. 다시말해 @Controller의 리턴값은 항상 주소를 반환 함 'return "/";'
14. @RestController이면 return에 적힌 메세지 자체를 응답해줌
15. 인터셉터는 어떤 인증이 필요한 요청이 들어오면 이 요청을 한 유저가 세션이 있는지 확인. 필터와 다른점은 필터는 애초에 다 걸러 버린다면, 인터셉터는 나중에 어떤 특정한 함수가 요청되고 그 요청이 중요한 요청(인증등) 일때 발동
☞ 회원가입 요청시를 예로 보자
1. 사용자가 회원가입 요청(INSERT)
'http://localhost:8000/join' 주소로 'POST' 요청 함 → HTTP BODY에 데이터가 담겨서 옴 (username/password/add...)2. 톰켓→필터→디스패처 작동
3. 디스패처가 INSERT함수를 가진 컨트롤러를 메모리에 띄움 → 이때 JDBC에 연결이 자동으로되고 세션이 만들어짐
4. 데이터를 가지고 서비스에 회원가입 요청 → 서비스단에서 트랜잭션이 발동
5. 서비스에서 레파지토리에 INSERT()를 요청 → 최초이니 DB에 바로 INSERT 요청
6. 정상적으로 INSERT가 되면 차례대로 질의응답결과값이 컨트롤러로 가고 컨터를로전 서비스에서 트랜잭션이 실행되면서 메모리에만 떠있던 INSERT값이 COMMIT이 됨 → 즉 서비스는 트랜잭션이고 이 트랜잭션 관리가 중요
7. 컨트롤러는 최종적으로 RETURN 메세지를 띄우거나(@RestController) 혹은 일반 페이지로 응답 (@Controller)
▲ 가장 에매모호한 Service의 역할
- 그럼 서비스는 트랜잭션만 관리하나? 아니다. 송금을 예로보자
1) A사용자가 B사용자에게 송금을 요청(REQUEST)
2) 컨트롤러는 송금(UPDATE)와 데이터를 가진 함수를 발동 → 서비스에게 송금 요청
(왜 업데이트일까? A 의 계좌 상태가 송금으로 달라지기 때문)3) 서비스는 JPA레파지토리에 UPDATE요청 → 레퍼지토리는 영속성을 체크해서 A오브젝트가 있으면 DB로 가지 않고
이 영속성에 있는 오브젝트를 업데이트해서 다시 컨트롤러까지 돌아감4) 이때 서비스에서 트랜잭션이 발동되고 커밋이 됨
5) 이 후 B의 계좌도 업데이트를 해야하는데 똑같은 방식으로 서비스 -> 레파지토리 -> 영속성 OR DB로 요청 함
하지만 만약 B 업데이트시 오류가 발생하면 ?
A는 업데이트가 끝나서 500만원이 빠졌지만 B는? 이럴때 필요한게 'ROLLBACK' (제일 처음 아무것도 하지 않는 상태)-> 즉 서비스는 DB 어떠한 요청과 응답사이에서의 커밋과 롤백을 관리하는 '하나의 기능' 이라고 보면 된다. 서비스는 어떠한 요청과 응답사이에서 하나의 오류라도 있으면 무조건 롤백을 시킨다.
'스프링 > 스프링부트+JPA - 블로그' 카테고리의 다른 글
스프링부트+JPA 블로그 프로젝트 10 카카오 로그인(OAuth2.0) (0) 2021.09.02 스프링부트+JPA 블로그 프로젝트 09 회원정보 수정(시큐리티) (0) 2021.09.01 스프링부트+JPA 블로그 프로젝트 07 게시판 (0) 2021.08.31 스프링부트+JPA 블로그 프로젝트 06 로그인(트랜잭션/시큐리티) (0) 2021.08.30 스프링부트+JPA 블로그 프로젝트 05 회원가입 개념(DTO/Ajax) (0) 2021.08.30