결국 무엇이든 해내는 사람

Spring Container? ContextLoaderListener란? 쉽게 쉽게 알아보자 본문

본격적인 공부 노트/Spring

Spring Container? ContextLoaderListener란? 쉽게 쉽게 알아보자

kkm8257 2024. 2. 20. 00:45
반응형
글의 목표
글을 짧고 내용은 간결하게 작성
내가 내 글을 보고 복습할 수 있게 작성

 

 

 

어떤 블로그를 읽어도,, 한방에 이해가 되진 않더라,,

내가 지식이 부족한 것도 있겠지만 뭔가 쌈@뽕하게 이해되는건 없길래,,, 여러 유튜브 강의와 블로그를 참조해가며 흐름의 순서대로 글을 작성해보려고한다.

 


 

톰캣으로 요청이 들어오면 제일 먼저 "web.xml"이 반겨준다.

이 web.xml에서 Spring 내부로 들어가기 위해 2가지 일을 한다.

 

 

먼저 DispatcherServlet이 동작을 한다. 이 DispatcherServlet은 "Component Scan"을 한다.

DispatcherServlet은 "Front Controller와 Request Dispatcher의 결합"이다.

DispatcherServlet은 주소분배의 역할을 한다. 어떤 주소가 들어왔을 때 어디로가! 어디로가!를 해줘야하니까!

 

 

"어디로 가려면 class들이 메모리에 떠있어야한다" 그래서 분배 뿐만 아니라 한가지 더 일을 한다. 

 

내용을 보기전에 static 선언된 클래스와 일반 클래스의 차이를 알아보자.

static은 main 메소드가 실행되기 전부터 떠있다.

일반 클래스는 생명주기(생성과 끝)가 분명히 존재한다.

 

다시 돌아와서, 우리의 프로젝트 폴더를 보면 "src"폴더안에 java 파일들이 모여있다. static으로 만들어진 클래스(파일)을 제외하고는 객체이므로, 생성하기 위해서는 "new"를 이용해서 생성해야하는게 맞다.

그런데 Spring은 "IoC"를 한다고 했다. 내가 "new"하지 않는다.

이걸 누가해준다? Dispatcher Servlet이 해준다. "컴포넌트 스캔"을 통해서! 스캔의 범위를 패키지별로 정할 수도 있으나 기본적으로는 패키지 전체를 스캔한다고 생각하면 쉽다.

그래서 패키지를 모두 뒤져서 필요한 클래스들을 메모리(IoC Container)에 올린다.

 

여기서 의문? 필요한 것과 필요하지 않는 것을 어떻게 구분하는가?

Spring은 이걸 "어노테이션"기법으로 구분한다. 

-- 인식하는 어노테이션 예시

@Controller
@RestController
@Configuration
@Repository
@Service

 

위에 적힌 어노테이션이 클래스에 명시되어있으면 IoC Container 메모리에 올라간다.

정리해보면

"컴포넌트 스캔을 통해 메모리에 뜬다" 이후 "분배" 할 수 있다. 왜? "떠있어야 분배할 수 있으니까!"

이게 Dispatcher Servlet의 중요한 목적이다.

컴포넌트 스캔을 통해 메모리에 띄우고 분배한다.

 

자 그런데 Dispatcher Servlet에 진입하기전에 먼저 수행되는 것이 있다.

ContextLoaderListener라는게 있다.

예를 들어 스레드를 20개를 설정했다고 가정하자. 첫 번째 요청이 들어오면 스레드 1이 생성되었고 그 스레드 1에는 필요한 객체들이 스레드 안에 생성된다. 두 번째 요청이 들어오면 새로운 스레드인 스레드 2가 생성되고 스레드 2에는 스레디 1과 똑같이 필요한 객체들이 스레드에 안에 생성된다.

그런데 컴포넌트 스캔을 통해 IoC에 띄운다고 했는데, IoC에서 가져다가 사용하더라도 스레드별로 객체를 각각 생성하고 스레드별로 따로 관리가 된다. 그러면 모든 스레드가 공통적으로 쓰는 것들이 있을 수도 있지않을까? 예를 들면 DB Connection 처럼!

이처럼 공통적으로 사용해도 되는 것들은 미리 ContextLoaderListener를 통해서 띄운다.

그러면 이 ContextLoaderListener는 어떤 xml파일을 읽는가? 바로 root-ApplictaionContext(ApplicationContext)파일이다. (파일은 xml이나 java파일로 커스텀할 수 있다)

root-ApplictaionContext파일은 스레드마다 따로 관리해야하는 파일말고 스레드들이 공통으로 사용하는 것들을 메모리에 띄워준다.

 

 

위 내용을 종합해보면 순서는 아래와 같다. (1번, 2번)

 

여기서 재밌는 사실

1번 과정을 통해 생성된 객체들은 2번 객체에 접근할 수 없다.

당연한 이야기인게,, 1번이 떠있을 때, 2번이 메모리에 있을리가 없으니까.

단, 반대는 가능하다.

"Dispathcher Servlet를 통해 메모리에 생성된 객체들은 ContextLoaderListener를 통해 메모리에 생성된 객체에 접근 할 수 있다."

 

 

 

프로세스 흐름

 

 

 

자 그럼 Spring Container가 뭔데?


스프링 컨테이너는 자바 객체의 생명주기를 관리하며, 생성된 자바 객체들에게 추가적인 기능을 제공한다. 스프링에서는 자바 객체를 

이라 한다. 즉, 스프링 컨테이너는 빈의 생명주기를 관리하고 추가기능을 제공한다.

스프링 컨테이너는 XML 혹은 어노테이션 기반의 자바 설정 클래스로 만들 수 있는데 Spring Boot를 사용하기전에는 xml로 직접 설정해 주어야했으나 Spring Boot가 등장하면서 대부분 사용하지 않게 되었다.

 

 

스프링 컨테이너는 BeanFactory와 ApplicationContext 두 종류의 인터페이스로 구현되어있다.

빈 팩토리는 빈의 생성과 관계 설정과 같은 제어를 담담하는 IoC 객체이고 이러한 빈 팩토리를 더 확장한 것이 애플리케이션 컨텍스트이다.

애플리케이션 컨텍스트는 IoC 방식을 따라 만들어진 일종의 빈 팩토리이고 주로 사용되는 스프링 컨테이너는 애플리케이션 컨텍스트이다.

 

BeanFactory

빈 팩토리(BeanFactory)는 스프링 컨테이너의 최상위 인터페이스이다.
BeanFactory는 빈을 등록, 생성, 조회 등의 빈을 관리하는 역할을 하며, getBean() 메서드를 통해 빈을 인스턴스화 할 수 있다.
@Bean 어노테이션이 붙은 메서드의 이름을 스프링 빈의 이름으로 사용하여 빈 등록을 한다.

 

여기에서 유의할 점은 여기에 등록하면 초기에 메모리에 로드되지 않고 필요할 때 getBean()으로 호출해서 메모리에 로드할 수 있다.

이 또한 IoC이다. 그리고 필요할 때 DI하여 사용할 수 있다.

ApplicationContext와 다른 점은 Bean Factory에 로드되는 객체들은 미리 로드되지 않고 필요할 때 호출하여 로드하기 때문에 

lazy-loading(게으른 로딩) 된다는 점이다.

 



ApplicationContext

애플리케이션 컨텍스트(ApplicationContext)는 BeanFactory의 기능을 상속받아 제공한다.
따라서, 빈을 관리하고 검색하는 기능을 BeanFactory가 제공하고, 그 외의 부가 기능을 제공한다.

부가 기능
- MessageSource : 메시지 다국화를 위한 인터페이스
- EnvironmentCapable : 개발, 운영, 환경변수 등으로 나누어 처리하고, 애플리케이션 구동 시 필요한 정보들을 관리하기 위한 인터페이스
- ApplicationEventPublisher : 이벤트 관련 기능을 제공하는 인터페이스
- ResourceLoader : 파일, 클래스 패스, 외부 등 리소스를 편리하게 조회

 

 

 

Spring Container의 기능


 

  1. 빈의 생명주기 관리
  2. DI를 통해 애플리케이션의 컴포넌트를 관리 가능
  3. 서로 다른 빈을 연결하여 애플리케이션 빈을 연결. 덕분에 개발자는 모듈 간에 의존 및 결합으로 발생하는 문제에서 자유로울 수 있다. 또한 메서드가 언제 어디서 호출되어야하는지, 메서드를 호출하기 위해 필요한 매개 변수를 준비해서 전달하지 않아도 된다.

 

 

자 그럼 Servlet Container가 뭔데?


2024.02.18 - [본격적인 공부 노트/Spring] - Spring Container? Spring MVC? Dispatcher Servlet 쉽게 쉽게 알아보자

 

 

반응형
Comments