본문 바로가기

spring

IOC(Inversion of Control)컨테이너 - 서블릿 컨테이너

스프링 프레임워크를 이해하는데 가장 중요한 개념이 바로 컨테이너이다. 컨테이너의 개념은 스프링에서 처음 사용된 것은 아니며, 기존의 서블릿이나 EJB 기술에서 사용해왔다. 그리고 대부분 컨테이너는 비슷한 구조와 동작 방식을 가지고 있으므로 서블릿 컨테이너를 통해 스프링 컨테이너의 동작 방식을 유추해볼 수 있다.

 

다음과 같이 간단한 서블릿 클래스를 만들었다고 가정하자.

HelloServlet.java

public class HelloServlet extends HttpServlet {
    public HelloServlet() {
        System.out.println("===> HelloServlet 객체 생성");
    }
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
                          throws ServletExetpion, IOException {
        System.out.println("doGet() 메소드 호출");                     
    }
}

 

이클립스를 이용하여 서블릿 클래스를 개발한다면 작성된 Servlet 클래스는 web.xml 파일에 자동으로 등록된다.

/WEB-INF/web.xml

<web-app>
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>hello.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello.do</url-pattern>
     </servlet-mapping>
</web-app>

 

위 설정된 브라우저에서 /hello.do라는 URL요청을 전송하면, hello라는 이름으로 등록된 hello.HelloServlet 클래스를 찾아 객체를 생성하고 실행한다는 설정이다. 이제 작성된 HelloServlet프로그램을 실행하면 다음과 콘솔에 출력되며, web.xml 설정대로 객체가 생성되고 실행되는 것을 확인할 수 있다.

<실행결과>

===> HelloServlet 객체생성
===> doGet() 메소드 호출

 

서블릿은 자바로 만들어진 클래스이다. 따라서 반드시 객체생성을 해야 객체가 가지고 있는 메소드도 호출할 수 있다. 그런데 작성된 소스 어디를 살펴봐도 객체 생성 코드를 볼 수 없으며, doGet() 메소드 호출 역시 확인할수 없다. 그렇다면 도대체 누가 서블릿 객체를 생성했으며, doGet() 메소드를 호출해줬을까? 정답은 바로 서블릿 컨테이너이다.

 

 

다음은 서블릿 컨테이너가 Servlet 클래스 객체를 생성하고 운용하는 과정을 그림으로 표현한 것이다.

서블릿 컨테이너의 서블릿 객체 관리

 

서블릿 컨테이너는 다음 순서에 따라 동작한다.

1. WEB-INF/web.xml 파일을 로딩하여 구동

2. 브라우저로부터 /hello.do 요청 수신

3. hello.HelloServlet 클래스를 찾아 객체를 생성하고 doGet() 메소드 호출

4. doGet() 메소드 실행 결과를 클라이언트 브라우저로 전송

 

이렇듯 컨테이너는 자신이 관리할 클래스들이 등록된 XML 설정 파일을 로딩하여 구동한다. 

그리고라이언트의 요청이 들어오는 순간 XML 설정 파일을 참조하여 객체를 생성하고, 겍체의 생명주기를 관리한다. 스프링 컨테이너 역시 서블릿 컨테이너와 유사하게 동작하므로 위에서 살펴본 요소들과 비슷한 요소들이 존재한다.

 

제어의 역행(IoC)은 결합도와 관련된 개념으로 이해할 수 있다. 기존에 자바 기반으로 애플리케이션을 개발할 때, 객체를 생성하고 객체들 사이의 의존관계를 처리하는 것에 대한 책임은 전적으로 개발자에게 있었다.

즉, 개발자가 어떤 객체를 생성할지 판단하고 객체 간의 의존관계 역시 소스코드로 표현해야 했다.

 

하지만 제어의 역행이라는 것은 이런 일련의 작업들을 소스코드로 처리하지 않고 컨테이너로 처리하는것을 의미한다. 따라서 제어의 역행을 이용하면 소스에서 객체 생성 의존관계에 대한 코드가 사라져 낮은 결합도 컴포넌트를 구현할 수 있게 한다.

 

'spring' 카테고리의 다른 글

Command 객체  (0) 2020.11.07
Spring MVC 구조 - (하)  (0) 2020.10.20
MVC 프레임워크 구현 - (중)  (0) 2020.10.03
@ModelAttribute와 커맨드 객체(2)  (0) 2020.09.06
@ModelAttribute와 커맨드 객체(1)  (0) 2020.09.06