스프링 MVC에서 서블릿 컨테이너 초기화는 서블릿 기반의 웹 애플리케이션이 실행될 때 컨테이너가 애플리케이션을 시작하고, 요청을 처리하는 구조를 설정하는 중요한 단계이다. 이를 이해하려면 서블릿 컨테이너와 스프링의 역할을 각각 분리해서 설명할 필요가 있다.

# 서블릿 컨테이너의 역할

서블릿 컨테이너는 Java EE (지금은 Jakarta EE) 웹 애플리케이션 서버에서 제공되는 컴포넌트로, 서블릿을 실행하고 관리한다. 서블릿은 HTTP 요청을 처리하고 응답을 생성하는 역할을 한다. 대표적인 서블릿 컨테이너는 Tomcat, Jetty, Undertow 등이 있습니다.

서블릿 컨테이너는 애플리케이션이 시작될 때 다음과 같은 일들을 수행한다:

  • 서블릿 등록 및 초기화: web.xml 파일이나 애노테이션 기반 설정을 통해 서블릿 클래스를 인식하고, 해당 서블릿을 초기화한다.
  • HTTP 요청 수신 및 전달: HTTP 요청이 들어오면 적절한 서블릿으로 요청을 전달하고, 서블릿이 응답을 생성하면 클라이언트에게 반환한다.

# 스프링 MVC의 역할

스프링 MVC는 서블릿 컨테이너 위에서 동작하는 웹 프레임워크로, 사용자 요청을 효과적으로 처리하고, 비즈니스 로직과 프레젠테이션 로직을 분리하는 역할을 한다. 스프링 MVC는 자체적으로 서블릿을 포함하지 않지만, 스프링 MVC를 동작시키기 위해 서블릿 컨테이너에 통합된다.

# DispatcherServlet

스프링 MVC의 중심이 되는 것은 DispatcherServlet다. 이 서블릿은 스프링에서 제공하는 프론트 컨트롤러로, 모든 HTTP 요청을 받아서 적절한 컨트롤러로 전달하고, 그 결과를 뷰로 변환하여 응답을 반환한다.

DispatcherServlet의 초기화 과정:

  1. 서블릿 컨테이너가 실행되면 스프링 애플리케이션에서 정의된 DispatcherServlet이 서블릿 컨테이너에 의해 로드된다.
  2. 서블릿 초기화 단계: DispatcherServlet이 초기화될 때, 스프링의 WebApplicationContext가 생성된다. 이 WebApplicationContext는 애플리케이션의 전반적인 설정과 빈(bean)들을 관리한다.
  3. 핸들러 매핑과 뷰 리졸버 설정: WebApplicationContext는 컨트롤러, 서비스, 레포지토리 등의 빈을 생성하고, 요청을 처리할 핸들러(컨트롤러 메서드)를 찾기 위한 매핑 정보도 설정한다. 또한 뷰를 어떻게 렌더링할 것인지 결정하는 뷰 리졸버도 설정된다.
  4. 요청 처리: 서블릿 컨테이너가 HTTP 요청을 수신하면 DispatcherServlet이 그 요청을 처리하고, 적절한 컨트롤러로 요청을 전달한 후, 결과를 다시 클라이언트에게 반환한다.

# ServletContext 초기화

DispatcherServlet을 서블릿 컨테이너에 등록하려면 ServletContext와 같은 객체를 사용해야 한다. 전통적으로 web.xml 파일을 사용하여 서블릿을 등록했지만, 최근에는 애노테이션과 자바 기반 설정이 더 많이 사용된다.

 

예시: 자바 기반 설정을 사용한 DispatcherServlet 등록

WebApplicationInitializer 인터페이스를 사용하여 서블릿 초기화 과정을 정의할 수 있다. 이 인터페이스는 서블릿 컨테이너가 초기화될 때 호출된다.

public class MyWebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(AppConfig.class); // 설정 클래스 등록

        DispatcherServlet dispatcherServlet = new DispatcherServlet(context);
        ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", dispatcherServlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
}

# 서블릿 3.0 이상에서의 편리한 초기화

서블릿 3.0 이상에서는 web.xml을 사용하지 않고 서블릿을 등록할 수 있는 애노테이션 기반 설정을 사용할 수 있다. @WebServlet, @WebFilter, @WebListener 같은 애노테이션을 사용하여 서블릿, 필터, 리스너를 직접 코드에서 설정할 수 있다.

스프링 MVC에서는 이를 더욱 편리하게 하기 위해 AbstractAnnotationConfigDispatcherServletInitializer 클래스를 제공하여, 개발자가 간단하게 서블릿 컨테이너에 DispatcherServlet을 등록할 수 있도록 돕는다.

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}

# 서블릿 컨테이너 초기화 지원 요약

  • 스프링 MVC에서 DispatcherServlet은 서블릿 컨테이너에 의해 관리되며, 모든 HTTP 요청을 프론트 컨트롤러 패턴을 사용해 처리한다.
  • 스프링은 자바 기반 설정이나 애노테이션을 사용하여 서블릿 초기화를 쉽게 지원하며, 서블릿 3.0 이후로는 코드 기반 서블릿 등록이 가능해졌다.
  • WebApplicationInitializer 또는 AbstractAnnotationConfigDispatcherServletInitializer 등을 사용하면 서블릿을 유연하게 초기화할 수 있다.

이 과정을 통해 스프링 MVC는 서블릿 컨테이너에서 실행되며, HTTP 요청을 받아서 적절한 핸들러(컨트롤러)로 전달하고, 결과를 클라이언트에게 반환하는 구조를 갖춘다.

'Java > Spring' 카테고리의 다른 글

스프링 컨테이너 정리  (0) 2024.09.20

스프링 컨테이너는 스프링 프레임워크의 핵심 구성 요소로, 애플리케이션의 객체를 관리하고, 이들의 생명주기와 의존성을 조정하는 역할을 한다. 스프링 컨테이너는 다양한 방식으로 객체를 생성하고 관리하며, 애플리케이션의 구조와 동작을 효율적으로 지원한다. 다음은 스프링 컨테이너에 대한 자세한 설명이다.

# 스프링 컨테이너의 주요 개념

  1. 의존성 주입(Dependency Injection, DI): 스프링 컨테이너는 의존성 주입을 통해 객체 간의 의존성을 자동으로 관리한다. 객체가 필요로 하는 의존 객체를 스프링 컨테이너가 자동으로 주입함으로써, 코드의 결합도를 낮추고 유연성을 높인다.
  2. 제어의 역전(Inversion of Control, IoC): 스프링 컨테이너는 객체 생성과 관리의 책임을 담당하며, 애플리케이션의 흐름을 제어한다. 이는 애플리케이션이 스프링 컨테이너에 의존하게 함으로써 객체 간의 결합도를 낮추고, 유지보수성을 향상시킨다.
  3. 빈(Bean): 스프링 컨테이너에서 관리되는 객체를 빈(bean)이라고 한다. 빈은 스프링 컨테이너에 의해 생성되고 관리되며, 애플리케이션의 주요 구성 요소로 사용된다.

# 스프링 컨테이너의 구성 요소

  1. ApplicationContext: 스프링 컨테이너의 가장 일반적인 구현체로, 애플리케이션의 빈을 생성하고 관리하며, 다양한 기능을 제공한다. ApplicationContext는 여러 구현체가 있으며, 가장 대표적인 것은 ClassPathXmlApplicationContext, FileSystemXmlApplicationContext, AnnotationConfigApplicationContext 등이 있다.
  2. BeanFactory: 스프링의 가장 기본적인 컨테이너로, 빈의 생성과 관리만 담당한다. BeanFactory는 ApplicationContext의 상위 인터페이스이며, 단순한 빈 관리 기능을 제공한다.
  3. Bean Definition: 빈의 생성과 관련된 정보를 정의하는 메타데이터로, 빈의 클래스, 초기화 메서드, 소멸 메서드, 의존성 등의 정보를 포함한다.

# 스프링 컨테이너의 동작 원리

  1. 빈 설정: 스프링 컨테이너는 애플리케이션의 설정 파일(XML 파일, 자바 클래스 등)에서 빈 정의를 읽어들인다. 설정 파일에는 빈의 클래스, 의존성, 범위(scope) 등의 정보가 포함된다.
  2. 빈 생성: 스프링 컨테이너는 빈 정의를 기반으로 빈을 생성한다. 빈 생성 과정에서 생성자 또는 팩토리 메서드를 사용하여 빈을 인스턴스화하며, 의존성 주입을 통해 필요한 의존 객체를 주입한다.
  3. 의존성 주입: 빈의 의존성을 해결하기 위해 스프링 컨테이너는 설정 파일에 정의된 의존성 정보를 참조하여 적절한 빈을 주입한다. 의존성 주입 방식에는 생성자 주입, 세터 주입, 필드 주입 등이 있다.
  4. 빈 초기화: 빈이 생성된 후, 초기화 메서드가 호출된다. 초기화 메서드는 빈이 사용되기 전에 필요한 초기 설정을 수행하는 메서드이다.
  5. 빈 사용: 빈이 초기화된 후, 애플리케이션 코드에서 빈을 사용하여 기능을 수행한다. 스프링 컨테이너는 빈을 관리하며, 빈 간의 의존성을 해결하여 애플리케이션의 요구를 충족한다.
  6. 빈 소멸: 애플리케이션 종료 시, 스프링 컨테이너는 빈의 소멸 메서드를 호출하여 빈 자원을 정리하고, 메모리를 해제한다.

# 빈의 범위 (Scope)

  1. 싱글톤(Singleton): 기본 빈 범위로, 애플리케이션당 하나의 빈 인스턴스만 생성된다. 모든 요청에서 동일한 빈 인스턴스가 반환된다.
  2. 프로토타입(Prototype): 빈의 범위가 프로토타입으로 설정되면, 요청할 때마다 새로운 빈 인스턴스가 생성된다. 빈의 상태가 독립적이며, 각각의 빈 인스턴스가 별도로 관리된다.
  3. 리퀘스트(Request): 웹 애플리케이션에서 사용되며, HTTP 요청당 하나의 빈 인스턴스가 생성된다. 요청이 완료되면 빈 인스턴스는 소멸된다.
  4. 세션(Session): 웹 애플리케이션에서 사용되며, HTTP 세션당 하나의 빈 인스턴스가 생성된다. 세션이 종료되면 빈 인스턴스는 소멸된다.
  5. 글로벌 세션(Global Session): 포트릿 기반의 웹 애플리케이션에서 사용되며, 글로벌 세션당 하나의 빈 인스턴스가 생성된다. 포트릿의 글로벌 세션이 종료되면 빈 인스턴스는 소멸된다.

# 스프링 컨테이너의 설정 방법 예시

1. XML 기반 설정: 스프링 2.0까지 주로 사용되던 설정 방법으로, XML 파일에 빈 정의와 설정을 한다.

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="exampleBean" class="com.example.ExampleBean">
        <property name="property1" value="value1"/>
    </bean>
</beans>
 

2. 자바 기반 설정: 스프링 3.0부터 도입된 설정 방법으로, 자바 클래스를 사용하여 빈 정의와 설정을 한다.

@Configuration
public class AppConfig {
    
    @Bean
    public ExampleBean exampleBean() {
        return new ExampleBean();
    }
}

3. 어노테이션 기반 설정: 스프링 2.5부터 지원된 설정 방법으로, 빈의 정의와 설정을 자바 클래스에 어노테이션으로 기술한다. @Component, @Service, @Repository, @Configuration 등의 어노테이션을 사용한다.

@Component
public class ExampleBean {
    
    @Value("value1")
    private String property1;
    
    // getters and setters
}

 

# 스프링 컨테이너의 주요 특징

  1. 유연성: 다양한 설정 방법(XML, 자바, 어노테이션 등)을 지원하여, 개발자가 선호하는 방식으로 컨테이너를 구성할 수 있다.
  2. 확장성: 다양한 기능을 제공하며, 애플리케이션의 요구에 따라 맞춤형 빈 설정, 사용자 정의 빈 팩토리 등을 지원한다.
  3. 통합성: 스프링 컨테이너는 다른 스프링 모듈(스프링 데이터, 스프링 AOP, 스프링 웹 등)과 통합되어 애플리케이션의 복잡성을 줄이고, 일관된 개발 환경을 제공한다.

스프링 컨테이너는 애플리케이션의 객체 관리와 의존성 주입을 통해 코드의 결합도를 낮추고, 유지보수성을 향상시키며, 애플리케이션의 구조를 효율적으로 구성할 수 있도록 지원한다. 이를 통해 개발자는 비즈니스 로직에 집중할 수 있으며, 애플리케이션의 품질과 확장성을 높일 수 있다.

'Java > Spring' 카테고리의 다른 글

스프링 MVC에서 서블릿 컨테이너 초기화 정리  (0) 2024.09.23

+ Recent posts