본문 바로가기

JAVA/- Spring

스프링 컨테이너, ApplicationContext, Bean Factory

스프링 컨테이너

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

request하면 톰켓이 반응합니다. web.xml을 보고 DispatchServlet이 동작합니다. DispatchServlet은 컴포넌트 스캔을 시작합니다. DispatchServlet은 주소를 분배하는 역할 뿐만아니라 메모리에 객체를 생성도 합니다.

자바파일은 static하지 않기 때문에 new해야 합니다. Ioc를 해야하기 때문에 DispatchServlet이 new를 해줍니다. src 폴더 밑에 있는 모든 파일을 new로 객체 생성 합니다.

이 때 필요 없는것과 필요 없는 것을 구분하는데 이것을 어노테이션으로 정해줍니다.
ex)" @Contorller가 붙은 것은 컨트롤러 역할이 있으니 스캔해서 올려놔~"

이 규칙은 스프링이 정해둔 것입니다.

 

 

DispatchSerlvet이 new로 객체를 생성 했습니다. 그럼 경로를 정해줄 수 있겠죠

reqeust를 하면 스레드를 생성합니다. 또다시 request가 오면 다시 객체를 생성하고 경로를 설정해야겠지요. request할 때 스레드가 공통적으로 사용되는 자원이 있습니다. DBConnection 입니다.

requestDispatchServlet에게 가기전에 ContextLoaderListenerroot_applicationContext.xml 파일을 읽습니다. 스래드들이 공통적으로 사용되는 것을 생성합니다. 이것이 첫 번째로 생성이 됩니다.

 

image

 

 

 

ApplicationContext

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

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이 된다는 점이다.

 

class에 @Configuration이 붙으면 컴포넌트 스캔할 때 메모리에 뜹니다.

객체를 return 하는 메소드는 @Bean을 사용해야 합니다.

 

 

 

요청 주소에 따른 적절한 컨트롤러 요청(Handler Mapping)

해당 주소 요청이 오면 적절한 컨트롤러의 함수를 찾아서 실행한다.

 

 

 

응답

html파일을 응답할지 Data를 응답할지 결정해야 하는데 html 파일을 응답하게 되면 ViewResolver가 관여하게 된다.

하지만 Data를 응답하게 되면 MessageConverter가 작동하게 되는데 메시지를 컨버팅할 때 기본전략은 json이다.

 

ex)

String Hello(){
    return "hello"
}

Hello()매서드를 ViewResolver가 관여하게 되면 WEB-INF/views/hello.jsp 라는 파일로 변환시켜서 응답합니다.

 

@ResponseBody
String Hello(){
    return "hello"
}

@ResponseBody를 붙히면 그냥 hello를 응답합니다.

 

 

 

User Hello(){
    return User
}

만약 객체를 응답으로 주면 MessageConverter동작해서 json으로 바꾸고 응답합니다.

ex)

{"id" : 1, "name": "홍길동"}
728x90