tistory 참고하면서 공부하자.
- FrontController 패턴
최초 앞단에서 request 요청을 받아서 필요한 클래스에 넘겨준다. 왜? web.xml에 다 정의하기가 힘들어서
이때 새로운 요청이 생기기 때문에 request와 response가 새롭게 new가 될 수 있다. 아래의 RequestDispatcher가 필요함.
기존의 있는 request와 response를 지우지 않고 그대로 들고와서 다시 요청을 하는 방법이 있다.
=> RequestDispatcher
- RequestDispatcher
필요한 클래스 요청이 도달했을 때 FrontController에 도착한 request와 response를 그대로 유지시켜준다.
결론적으로 RequestDispatcher을 이용해야 데이터를 들고 페이지간 이동이 가능하다.
스프링에서는 RequestDispatcher을 대체할 DispatchServlet가 있다.
DispatchServlet
FrontController 패턴을 직접짜거나 RequestDispatcher를 직접 구현할 필요가 없다.
스프링에는DispatchServlet 있음 ^_^
DispatchServlet는 FrontController 패턴 + RequestDispatcher이다.
DispatchServlet이 자동생성되어 질 때는 수 많은 객체가 생성(IoC)이 되어지고, 보통 필터들인데 해당 필터들을 사용자가 직접 등록할 수 있고 기본적으로 필요한 필터들은 자동으로 등록이 가능해진다.
ApplicationContext
스프링 컨테이너
DispatchServlet에 의해 생성되어지는 수 많은 객체들은 아래에서 관리된다.
첫째, ApplicationContext
수 많은 객체들이 ApplicationContext에 등록이 되고 이걸 IoC라고 부른다. IoC란 제어의 역전을 의미하고 개발자가 직접 new를 통해서 객체를 생성하게 되면 해당 객체를 가르키는 레퍼런스 변수를 관리하기 어렵다. 그래서 스프링이 직접 해당 객체를 관리하는데 이때 주소를 몰라도 된다. 필요할 때 DI 의존성 주입을 하면 되기 때인이다. 필요한 곳에서 ApplicationContext에 접근해 필요한 객체를 가져올 수 있다. ApplicationContext는 싱글톤으로 관리되기 때문에 어디에서 접근하든 동일한 객체라는 걸 보장해준다.
ApplicationContext의 종류에 두가지가 있다. (root-applicationContext와 Servlet-applicationContext) 이다.
servlet-applicationContext는 ViewResolver, Interceptor, MultipartResolver 객체를 생성하고 웹과 관련된 어노테이션 Controller, RestController를 스캔한다.
==> 해당 파일은 DispatchServlet
에 의해 실행된다.
root-applicationContext는 해당 어노테이션을 제외한 어노테이션 Service, Repository 등을 스캔하고 DB 관련 객체를 생성한다.(스캔이란 : 메모리에 로딩한다는 뜻이다.)
====> 해당 파일은 ContextLoader에 의해서 실행된다. ContextLoaderListener를 실행해주는건 web.xml이여서
root - applicationContext는 servlet-applicationContext보다 먼저 로드 된다.
servlet-applicationContext에서 root-applicationContext가 로드한 객체를 참조할 수 있지만
반대는 불가능 / 생성 시점이 다르기 때문이다.
Servlet Container에서는
web.xml 로딩 -> ContextLoaderListener 로딩 -> root-context.xml 실행 / 모든 스레드들이 공유해서 사용하면 되는 것들을 메모리에 띄운다.
둘째, Bean Factory
- 필요한 객체를 Bean Factory에 등록할 수도 있다. 여기에 등록하면 메모리에 초기에 로드되지 않는다,.
- 필요할 때 getBean()이라는 메소드를 통해(그냥 메소드 위에 @Bean 붙이면 된다.) 호출해서 메모리에 로드할 수 있다.
- 또한 IoC이다. 필요할 때 DI하여 사용할 수도 있고 ApplicationContext와 다른 점은 Bean Factory에 로드되는 객체들은 미리 로드되지 않고 필요할 때 로드하기 때문에 lazy-loading가 된다는 점이다.
@Configuration 붙일때 클래스 A가 메모리에 뜬다. (컴포넌트 스캔을 할 때)
메소드 위에 @Bean 어노테이션을 붙여서 메모리에 띄울 수 있다.
모든 스레드가 공통적으로 사용하는 것들은 ContextLoaderListener DB에 띄운다.
DispatcherServlet이 메모리에 띄운 것들은 DB에 접근이 가능하다.
root-ApplicationContext 파일에서 메모리에 띄워서 class들이 필요할 때마다 DB에 접근해서 가져와 쓴다.
요청 주소에 따른 적절한 컨트롤러로 요청(Handler Mapping)
GET요청 => http://localhost:8080/post/1
해당 주소 요청이 오면 적절한 컨트롤러의 함수를 찾아서 실행
응답
html 파일을 응답할지 Data을 응답할지 결정해야 하는데 html 파일을 응답하면(jsp) ViewResolver가 관여하게 된다.
Data를 응답하게 되면 MessageConverter가 작동해서 메시지를 컨버팅할 때 기본전략은 json이다.
Jacson말고 MySon이라는 데이터타입이 들어왔을 때 MessageConverter가 작동해서 자동으로 동적파일 실행되서 MySon을 호출해준다.
초반세팅 => 비즈니스 로직 순
톰캣 실행시
초반세팅
web.xml이 먼저 로드되고 해야 할일들을 쭉 살핀다. 굉장히 많다.
다음 ContextLoaderListener이 Create되고 root-context.xml(applicationContext.xml이 읽어질 때)이 로딩이 된다. DB와 관련된 객체들이 컴포넌트 스캔해서 메모리에 올려진다.(ServiceImpl, DAO, VO) 미리 띄워야 할것들은 ContextLoaderListener을 통해서 db관련된 것들을 띄워놓는다.
그 다음 사용자로부터 Request 요청이 들어오게 된다.
간단하게 설명하면 톰캣 실행시 web.xml이 로딩이 되고 이때 DB와 관련된 객체가 메모리에 올라가고 Client로부터 request를 받았을 때 DispatcherServlet이 web.xml의 FrontController패턴으로 역할을 분배해서 웹과 관련된 애들을 Controller에 띄우고 주소분배를 한다.
그리고 응답 Response 하게 될때 Data로 리턴할 지 html파일로 리턴할 지 결정이 끝나면 정상적인 로직이 실행된다.
<출처: 스프링부트 개념정리 with JPA 12강 - DispatcherServlet>
https://www.youtube.com/watch?v=fZv9rkwSO3g&list=PL93mKxaRDidG_OIfRQ4nztPQ13y74lCYg&index=12
<출처:스프링부트 개념정리 with JPA 13강 - ApplicationContext>
https://www.youtube.com/watch?v=YRdS7qcZ8AY&list=PL93mKxaRDidG_OIfRQ4nztPQ13y74lCYg&index=13
<출처:스프링부트 강좌 with JPA 14강(마지막) - 응답(Response)하는 방법>
https://www.youtube.com/watch?v=GCx65TdiA44&list=PL93mKxaRDidG_OIfRQ4nztPQ13y74lCYg&index=14
'Spring > SpringBoot' 카테고리의 다른 글
Spring Boot으로 웹출시 - thymeleaf를 이용한 화면 작성 (0) | 2022.05.30 |
---|---|
Spring Boot으로 웹 출시까지 (0) | 2022.05.30 |
서블릿 객체의 생명주기 & web.xml (0) | 2022.05.06 |
Tomcat (0) | 2022.05.06 |
ORM & 영속성 컨텍스트 & OOP 관점 모델링 & HTTP (0) | 2022.05.06 |