Spring과 MVC

백엔드 개발자를 꿈꾸는 사람들에게는 공통적인 조언이 따르는 것을 보았습니다. 그 조언은 바로 ‘백엔드? 무조건 스프링해라’라는 것입니다. 한국에서 SI 업체들이 정부의 하청을 많이 받는데, 대한민국 정부에서는 자바 기반의, 스프링으로 만들어진 ‘전자정부프레임워크’를 사용하기 때문에 다른 백엔드 프레임워크에 비해 스프링을 사용하는 경우가 월등히 많다고 합니다.
뭐 그래서.. 스프링이 뭔지 알아봤습니다.

스프링(Spring)의 어원

스프링 이전에는 EJB라는 기술을 통해 웹 애플리케이션을 개발했지만 이는 굉장히 복잡했습니다. 이런 단점을 보완하고자 만들어진 기술 중 으뜸이었던 기술이 바로 스프링입니다. 스프링은 EJB 없이도 고품질의, 확장 가능한 애플리케이션을 개발할 수 있는 프레임워크이고, 오픈 소스 프로젝트로 제안되면서 전통적인 EJB라는 겨울을 넘어 새로운 시작이라는 뜻으로 Spring이라는 이름을 가지게 되었습니다.

프레임워크(Framework)란?

프레임워크는 뼈대나 기반 구조를 뜻하고, 제어의 역전(IoC) 개념이 적용된 대표적인 기술입니다. 소프트웨어에서의 프레임워크는 ‘소프트웨어의 특정 문제를 해결하기 위해서 상호 협력하는 클래스와 인터페이스의 집합’이라고 할 수 있으며, 완성된 애플리케이션이 아닌 프로그래머가 완성시키는 작업을 해야 합니다.
라이브러리는 단순 활용 가능한 도구들의 집합입니다. 개발자가 만든 클래스에서 호출하여 사용, 클래스들의 나열로 필요한 클래스를 불러서 사용하는 방식을 취합니다.

  • 제어의 역전은 프로그래머가 직접 객체의 생성과 소멸, 객체간 관계같은 객체의 제어를 수행하는 것이 아니라 여러 프레임워크, 컨테이너에서 제어를 수행하는 것입니다. 확장 가능하고 모듈화된 프로그램을 구성하는 느슨한 결합을 달성하기 위해 다양한 종류의 컨트롤을 반전하는 것을 의미하며, 클래스간의 결합을 느슨하게 설계하여 테스트가 가능하고 유지보수가 용이하게 만드는 데 도움이 됩니다.
  • 객체지향에서 다른 객체를 사용하는 것을 다른 객체의 의존한다고 표현합니다. 의존성 주입은 객체 외부에서 내부로 주입받아서 사용하는 방식입니다. 보통은 클래스를 만들때 인스턴스화를 막기 위해 private 생성자로 만드는데, 보통 구현하게 되면 강한 결합의 경우 오류가 발생합니다. 강한 결합과 의존성의 문제를 해결하기 위해 스프링과 같은 프레임워크에서는 웹을 구현하기 위한 많은 클래스들을 이미 구현해두었고, 개발자는 이를 주입받아서 사용할 수 있습니다.

프레임워크는 애플리케이션의 흐름을 스스로 쥐고 있으며, 사용자는 그 안에서 필요한 코드를 짜 넣습니다.

스프링 프레임워크(Spring Framework)

스프링 프레임워크는 자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크입니다.

  • 애플리케이션 프레임워크: 특정 계층이나 기술, 업무 분야에 국한되지 않고 애플리케이션의 전 영역을 포괄하는 범용적인 프레임워크로, 애플리케이션 개발의 전 과정을 빠르고 편리하며 효율적으로 진행하는데 일차적인 목표를 두는 프레임워크입니다.
  • 경량급: 툴의 도움 없이는 다루기 힘든 난해한 설정 파일 구조와 까다로운 패키징, 불편한 서버 배치 등으로 인한 부담을 없애고, 쉽게 해당 기능들을 사용할 수 있게 되었음을 의미합니다.

스프링 프레임워크의 특징

  1. 경량 컨테이너
    • 경량 컨테이너로서 자바 객체를 직접 관리합니다.
    • 각각의 객체 생성, 소멸과 같은 라이프 사이클을 관리하며 스프링으로부터 필요한 객체를 얻어올 수 있습니다.
  2. POJO 기반의 구성
    • Plain Old Java Object, 즉 평범한 자바 객체를 말합니다.
    • 단, POJO는 특정 규약과 특정 환경에 종속되어서는 안되고 객체지향 설계를 잘 지켜야한다는 조건이 있습니다.
  3. DI를 통한 객체 간의 관계 구성
    • 스프링은 그 자체가 구조를 설계할 수 있어서 개발자가 부품을 만들어 조립하는 형태의 개발이 가능합니다.
    • 이렇게 조립된 코드의 최종 호출은 개발자가 결정하는 것이 아니라 스프링 프레임워크 내부에서 이루어지는데, 이것을 제어의 역행(IoC)이라고 합니다.
    • 의존성 주입(DI)은 제어의 역행이 일어나는 것을 전제로 하여 스프링 내부의 객체들 간의 관계를 만들어줄 때 사용합니다. 특정 객체가 필요로 하는 객체를 외부에서 결정하여 연결시키는 것을 의미합니다.
  4. AOP 지원
    • AOP(Aspect Oriented Programming)은 관점 지향 프로그래밍입니다.
    • 대부분의 시스템에서 비즈니스 로직은 아니지만 보안, 로그, 트랜잭션과 같이 반드시 처리가 필요한 부분을 ‘횡단 관심사’라고 합니다. 스프링에서는 이러한 관심사를 비즈니스 로직과 분리하여 중복된 코드를 줄이고 개발자가 비즈니스 로직에 집중하도록 만들어 줍니다.
  5. WAS에 독립적인 개발 환경
    • 과거의 EJB가 동작하려면 고가의 느리고 무거운 자바 서버(WAS)가 필요했습니다. 하지만 스프링은 가장 단순한 서버 환경인 Tomcat이나 Jetty에서도 완벽하게 동작합니다.
    • 단순한 개발툴과 기본적인 개발환경으로도 엔터프라이즈 개발에서 필요로 하는 ‘주요한 기능을 갖춘 애플리케이션’을 개발하기에 충분합니다.
  6. 이외에도 트랜잭션 관리, API와의 영속성 지원(JDBC, JPA 등) 등을 한다는 특징이 있습니다.

Spring MVC

스프링 MVC는 스프링에서 제공하는 웹 모듈로, Model, View, Controller 세 가지 구성요소를 사용해 사용자의 다양한 HTTP Request를 처리하고 단순한 텍스트 형식의 응답으로부터 REST 형식의 응답은 물론 View를 표시하는 HTML을 반환하는 응답까지 다양한 응답을 할 수 있도록 하는 프레임워크입니다.
스프링 MVC는 다양한 요청을 처리하고 응답하기 위해 주요 구성요소들을 만들어 놓고 구성요소들을 확장할 수 있게 만들어 놓는데, 이를 제대로 사용하기 위해서는 MVC가 어떻게 구성되어 있는지를 알아야 합니다.

Spring MVC의 구조

스프링 MVC의 주요 구성요소는 Model, View, Controller지만, 이들이 유기적으로 동작하도록 하기 위해 다양한 구성요소가 함께합니다. image

  • DispatcherServlet(Front Controller)
    • 제일 앞단에서 HTTP Request를 처리하는 Controller입니다.
    • 스프링 MVC에서는 HTTP Request가 오면 DispatcherServlet이라 불리는 서블릿이 HTTP Request를 처리할 Controller를 지정합니다.
    • DispatcherServlet은 일종의 HTTP Request를 처리할 Controller를 지정하는 Controller로, Super Controller 역할을 합니다.
  • Handler(Controller)
    • HTTP Request를 처리해 Model을 만들고 View를 지정합니다.
    • DispatcherServlet에 의해 배정된 Controller는 HTTP Request를 처리하고, HTTP Request의 메세지를 처리해 필요한 데이터를 뽑아 Model에 저장합니다.
    • HTTP Request에 따라서 HTTP가 보여줄 View Name을 지정합니다. 이곳에서 View Name을 지정하는 것 뿐만 아니라 직접 View를 반환할 수도 있습니다. 하지만 이곳에서 View에 Model의 데이터를 세팅하지는 않습니다.
  • ModelAndView
    • Controller에 의해 반환된 Model과 View가 Wrapping된 객체입니다.
        public ModelAndView(String viewName, @Nullable Map<String, ?> model){
        this.view = viewName;
        if(model != null){
            getModelMap().addAllAttributes(model);
        }
        }
      
    • Model: Map<String, Value> 형태의 데이터 저장소로, HTTP Request 속의 데이터를 파싱해 Key-Value 쌍으로 만들어 저장합니다. 이 Model은 이후에 View를 그리기 위해 사용합니다.
    • View, ViewName: ViewResolver에서 그릴 View를 지정합니다.
    • ModelAndView 내부에는 View 또는 ViewName이 있는데, View가 지정되더라도 데이터가 세팅된 View가 지정되지 않습니다.
  • ViewResolver
    • ModelAndView 객체를 처리해 View를 그립니다. 여기서는 Model에 저장된 데이터를 사용해 View를 그립니다.
    • View는 사용자에게 보여줄 완성된 View이며, 여기서 그려지는 View는 그대로 유저에게 반환됩니다.
    • 특정한 URL로 들어갔을 때 우리에게 보여지는 View가 바로 이곳에서 만들어지는 View입니다.

Spring MVC의 의의

  • Spring MVC는 웹 애플리케이션을 유연하고 확장 가능하게 만들어줍니다.
  • Spring MVC는 HTTP Request를 처리하는 부분인 Controller, 데이터를 처리해 정제된 데이터를 넣는 Model, 정제된 데이터를 활용해 사용자에게 보여지는 View에 대한 역할 분리를 잘 해놓았습니다.
  • 이를 사용하면 Model, View, Controller 모두를 인터페이스를 사용해 규격화하여 유연하고 확장성있게 웹 애플리케이션을 설계할 수 있습니다.

참고