Springboot 개념정리 - ApplicationContext

Yuri Lee·2020년 9월 10일
0

Springboot 개념정리

목록 보기
9/10

스프링부트 강좌 with JPA 13강 - ApplicationContext가 무엇인가요?

DispatchServlet에 의해 생성되어지는 수많은 객체들은 어디에서 관리될까?

외부에서 request 요청이 온다. 아파치는 스프링에서 지우자. 스프링에서는 모두 자바파일을 요청한다. request 요청을 하면 톰켓이 작동한다. web.xml에서 처음으로 스프링 내부로 들어가기 위해 2가지 일을 한다.

dispatchServlet이라는 얘가 동작을 한다. 얘가 컴포넌트를 스캔한다. dispatchServlet (frontController + RequestDispatcher) 얘의 궁극적인 목적은 주소를 분배하는 것이다. 분배뿐만 아니라 다른 일을 더 하는데, 분배를 하려면 메모리에 떠있어야 한다.

얘가 어떤 요청이 들어왔을 때 어디로 가야 하는 클래스들이 여러개 있을 것이다. 클래스들이 메모리에 떠있어야 보낼 수 있다.

주소를 분배하기 전에..

src 소스폴더 안에 자바파일이 모여있다. 수많은 자바파일들이 메모리에 떠있어야 한다.

static, 자바파일 두개는 다르다. static는 main 메소드가 실행되기 전부터 메모리에 떠있는다. 그래서 집으로 비유한다면 태초에 존재하는 얘들이 static 이다. 근데 객체로 메모리에 띄우는 것은

1990~2005
1990~2050

이런 식으로 생성과 사라짐이 일어날 수 있는 것이다. 특정한 타임에 메모리에 떴다가 사라지는 것을 의미한다.

~~자바파일에서는 우리가 만든 클래스들이 메모리에 떠있으려면,
자원은 하나밖에 없지만 ,,,,
~~
대부분 new가 되어야 하니까 메모리를 띄어야 한다 .근데 스프링은 내가 new를 하지 않는다. ioc를 하기 때문이다. 그 new를 dispatcherServlet를 한다. 컴포넌트 스캔을 통해서 ..

src 내부에 있는 모든 파일을 ..

스프링 부트 버전부터 특정 패키지 이하를 다 스캔한다.
com.cos.blog... 자동으로 패키지 이하로 잡힌다.

이 이하에 있는 자바 파일을 뒤져서 필요한 얘들을 올린다. 그럼 여기서 필요한 것을 어떻게 알음? 이것을 어노테이션으로 정해놓음.

@Controller,
@ ResController, @Configration, @Repository, @ Service, @Component 등등 ..

이 어노테이션을 찾는다. 그리고 메모리에 띄우는 것이다. 이것은 스프링이 정해놓은 것이다. 얘들이 어떤 역할을 하는지 배워야 한다.

ioc 컨테이너에 어떤 자바클래스를 객체로 띄우고 싶으면 어떤 어노테이션으로 메모리에 띄울 수 있느냐를 알아야 한다. 기본적으로 제공하는 어노테이션을 통해 웹 서비스를 구축할 수 있다. 이것을 나중에 다 공부를 해야 한다. 이런 것들이 붙어있는 것을 dispatch servlet이 스캔한다는 것이다. 그래서 메모리에 얘들이 떠서 분배할 수 있는 것이다. 떠있지 않으면 분배시킬 수 없다.

컴포넌트 스캔하고 주소를 분배한다. 근데 이거 말고 여기에 진입하기 전에 하는일이 하나 더 있다.

Context loader listner

서블릿이 만들어지면, 스레드가 만들어진다. 요청한 사람이 100명이면 스레드가 20개까지 만들어질 수 있다면 20개에 대한 스레드만 만들어진다. 각각의 스레드는 독립적이기 때문에 서로 영향을 받지 않는다. 두번째 요청이 들어왔을 때는 새로운 스레드가 만들어진다. 또 새로운 객체가 만들어지니까 충돌날 일이 없다.

컴포넌트 스캔을 통해 메모리에 ioc로 띄운다고 했는데 ..이것보다
모든 요청한 얘들이 공통적으로 쓰일 수 잇는게 있다. 바로 DB에 관련된 것이다. 그런 것들을 미리 ContextLoaderListner을 통해 띄운다.

root- ApplicationContext라는 파일을 읽는다. xml 파일로 커스터마이징할 수도 있고..등..

중요한건 컨텍스트로드리스너가

공통적으로 사용해야 할 것을 메모리에 띄어준다.
그리고 ioc 컨테이너에서 관리해준다. 여기 디비에서


DispatcherServlet에 의해 생성되어지는 수 많은 객체들은 ApplicationContext에서 관리된다. 이것을 IoC라고 한다.

ApplicationContext

수많은 객체들이 ApplicationContext에 등록된다. 이것을 ioc라고 한다. 어떻게 등록이 될까? dispatchServlet이 component 스캔할 때 등록이 된다.

IoC란 제어의 역전을 의미한다. 개발자가 직접 new를 통해 객체를 생성하게 된다면 해당 객체를 가르키는 레퍼런스 변수를 관리하기 어렵다. 그래서 스프링이 직접 해당 객체를 관리한다. 이때 우리는 주소를 몰라도 된다. 왜냐하면 필요할 때 DI하면 되기 때문이다.

DI를 의존성 주입이라고 한다. 필요한 곳에서 ApplicationContext에 접근하여 필요한 객체를 가져올 수 있다. ApplicationContext는 싱글톤으로 관리되기 때문에 어디에서 접근하든 동일한 객체라는 것을 보장해준다.

ApplicationContext의 종류에는 두가지가 있는데 (root-applicationContext와 servlet-applicationContext) 이다.

a. servlet-applicationContext
서블릿....웹만 바라보는..

servlet-applicationContext는 ViewResolver, Interceptor, MultipartResolver 객체를 생성하고 웹과 관련된 어노테이션 Controller, RestController를 스캔 한다.

============> 해당 파일은 DispatcherServlet에 의해 실행된다.

b. root-applicationContext
최상단...

root-applicationContext는 해당 어노테이션을 제외한 어노테이션 Service, Repository등을 스캔하고 DB관련 객체를 생성한다. (스캔이란 : 메모리에 로딩한다는 뜻)

============> 해당 파일은 ContextLoaderListener에 의해 실행된다. ContextLoaderListener를 실행해주는 녀석은 web.xml이기 때문에 root-applicationContext는 servlet-applicationContext보다 먼저 로드 된다.

당연히 servlet-applicationContext에서는 root-applicationContext가 로드한 객체를 참조할 수 있지만 그 반대는 불가능하다. 생성 시점이 다르기 때문이다.

Bean Factory

필요한 객체를 Bean Factory에 등록할 수 도 있다. 여기에 등록하면 초기에 메모리에 로드되지 않고 필요할 때 getBean()이라는 메소드를 통하여 호출하여 메모리에 로드할 수 있다. 이것 또한 IoC이다. 그리고 필요할 때 DI하여 사용할 수 있다. ApplicationContext와 다른 점은 Bean Factory에 로드되는 객체들은 미리 로드되지 않고 필요할 때 호출하여 로드하기 때문에 lazy-loading이 된다는 점이다.


-이 글은 유투버 겟인데어의 스프링 부트 강좌를 바탕으로 정리한 내용입니다.-

profile
Step by step goes a long way ✨

0개의 댓글