Spring

CGI에서부터 Spring에 이르기까지

teo_99 2023. 9. 19. 00:55

현재 스프링 구조에 대한 학습을 진행하고 있습니다. 백엔드 개발을 하면서 다양한 스프링 지원기술들을 사용해왔지만, 정작 이 기술들이 왜 생겨나게 되었는지, 스프링은 왜 등장했는지에 대해 명확히 이해하지 못했던 것 같습니다. 따라서 이번 아티클을 통해 스프링의 등장 배경을 정리해보도록 하겠습니다. 

 

들어가면서

웹 어플리케이션의 발전 과정

사실 스프링이 등장하기까지는 많은 발전 과정이 존재했습니다. 초기 WWW 모델을 거쳐 CGI, Servlet, JSP 기술이 등장한 뒤에서야 스프링이 등장하게 되었습니다.

 

그렇다면 스프링은 어떤 문제를 해결하기 위해 등장한걸까요? CGI, Servlet, JSP의 특징을 알아보면서 스프링이 등장하게 되었던 당위성을 이해해보고자 합니다.

 

CGI

WWW이 발전함에 따라, 정적 웹페이지가 아닌 동적 웹페이지에 대한 요구가 늘어나게 되자 CGI라는 기술이 등장했습니다. CGI란, Common Gateway Interface의 약자로 서버와 애플리케이션 간에 데이터를 주고 받는 방식을 의미합니다. 

 

CGI 방식의 웹 어플리케이션

초기의 웹 서버에서는 동적 웹페이지를 구성하기 위해 따로 프로그램을 실행시켰습니다. 사용자의 요청이 들어오면 해당 요청에 맞는 적절한 프로그램을 실행시켜서 동적 웹페이지를 만들어 반환했다는 이야기입니다. 그리고 서버가 사용자 요청에 대응되는 프로그램을 실행시키기 위해 사용했던 인터페이스가 바로 이 CGI입니다.

 

예를 들어, 사용자가 장바구니 화면 조회 요청을 보내는 경우에는 다음과 같이 동적 페이지를 구성했습니다.

장바구니 조회 요청 시나리오(CGI 기반)

이런 CGI 인터페이스를 활용한 방식은 동적 웹페이지를 구성할 수 있었지만, 다음과 같은 문제점들이 존재했습니다.

  • 매 요청마다 프로그램을 실행해야 하니 서버 자원이 많이 소모됩니다.
  • 매 요청마다 프로세스를 할당하는 구조였기 때문에 서버 부하가 상당했습니다.
  • CGI 어플리케이션은 C, C++, Perl 등의 언어로 구성되기 때문에 특정 플랫폼에 종속적입니다.

그리고 이런 문제점들을 해결하기 위해 Servlet이 등장했습니다.

 

Servlet

Servlet은 자바를 사용해서 웹페이지를 동적으로 생성하는 기술을 의미합니다. Servlet으로 구현된 웹 어플리케이션 서버는 프로세스가 아닌 스레드 기반으로 동작하며, 매 요청마다 외부 프로그램을 실행할 필요가 없습니다. 또한, Servlet은 Java로 짜여지기 때문에 특정 플랫폼에 종속적이지도 않습니다. 즉, CGI의 단점을 극복하는 버전이 바로 Servlet이라고 할 수 있겠습니다.

 

Servlet은 다음과 같은 기본 흐름을 가집니다.

Servlet 방식의 웹 어플리케이션에서는 앞서 설명드렸다시피 요청이 발생하면 프로세스가 아닌 스레드를 할당하게 되고, 적절한 Servlet을 찾아 동적 웹페이지를 생성합니다.

 

Servlet은 매 요청마다 새로 생성되거나 하는 게 아니라, 'service' 라고 하는 특정 메소드만 호출되어 요청을 처리하기 때문에 어플리케이션을 실행하는 방식(CGI 방식)과 비교해서 경제적입니다.

 

Servlet 방식의 웹 어플리케이션은 대개 Servlet Container를 가집니다. Servlet을 초기화해주고 호출하는 '누군가'가 필요하기 때문입니다. Servlet Container는 Servlet을 관리해주면서, 웹소켓 통신을 제공하는 등 동적 웹페이지를 제공하기 위한 기타 작업을 수행해줍니다.

Spring Boot를 사용하는 경우 기본적으로 Embedded Tomcat을 사용하는데, 이 Tomcat이 하는 역할이 바로 서블릿 컨테이너입니다.

 

그렇지만 서블릿 방식의 웹 어플리케이션도 다음과 같은 문제점은 존재했습니다. 

  • 자바 코드에서 HTML을 직접적으로 다루다보니 뷰의 영역이 모호했습니다. 비즈니스 코드와 뷰의 영역을 함께 다루어야 하니 복잡도가 올라갔습니다.

 

JSP

따라서 JSP가 등장합니다. JSP는 Java Server Page의 약자로(현재는 Jakarta Server Page라고도 불립니다) HTML 코드에 Java 코드를 넣어 동적 웹페이지를 생성하는 기술을 의미합니다.

<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>JSP example</title>
</head>
<body>
	<p>
    	<form method = "get" action = "login.jsp">
        <%
            String id = request.getParameter("id");
            String password = request.getParameter("password");
            
            if (password.equals("1234")) {
            	out.write("Hello world!");
            } else {
            	out.write("Login Failed!");
            }
        %>
</body>
</html>

위는 JSP의 구조인데, 자세히 보시면 <% %> 블록 안에 Java 코드가 포함되어 있는 것을 확인하실 수 있습니다. 이 <% %>와 같은 친구들을 JSP 태그라고 하는데, JSP에서는 JSP 태그를 활용해 Java 코드를 HTML에 삽입할 수 있습니다. 이렇게 JSP를 사용하면 비즈니스 로직과 뷰의 경계가 뚜렷해지고 쉽게 HTML 파일에 값을 넣을 수 있었습니다. 참고로, 이런 JSP 파일들은 런타임에 Servlet 객체로 변환이 되므로 결국은 동일한 역할을 한다고 이해하시면 될 것 같습니다.

 

이런 JSP는 어떤 방식으로 사용하느냐에 따라 모델 1 구조와 모델 2 구조가 존재합니다. JSP를 통해 뷰의 구성과 비즈니스 로직의 처리까지 모두 수행한다면 모델 1 이라고 불렸고, 뷰의 구성만 담당한다면 모델 2라고 불렸습니다.

 

Model 1 vs. Model 2

모델 1의 경우에는 구조가 단순하여 간단한 페이지를 구성하는 데에 주로 사용되었지만, 결국은 비즈니스 로직과 뷰의 코드가 한 곳에서 관리되기 때문에 어려움을 겪었습니다.

 

따라서 모델 2가 등장했는데, 모델 2의 경우는 모델 1을 보완한 것으로 로직 처리 자체는 서블릿이 하며 JSP는 렌더링만 담당하게 됩니다. 즉, 각각의 책임에 맞게 관심사의 분리를 적절히 응용하여 유지보수성을 향상시킨 모델입니다. 그리고 이 구조는 현재 우리에게 익숙한 MVC 패턴과 유사합니다.

 

J2EE와 EJB

이런 Servlet, JSP와 같은 기술들이 제안된 곳이 바로 J2EE(Java to Enterprise Edition)입니다. J2EE란, 쉽게 말해 기업 환경의 어플리케이션을 구성하기 위해 필요한 표준의 집합을 의미합니다.

 

많은 개발자들은 이 J2EE라는 표준을 따르며 개발을 진행해왔습니다. J2EE에는 JDBC, Servlet, JSP 등 개발을 해보았다고 한다면 무조건 한번쯤은 들어보았을만한 표준이 많이 존재합니다. 그렇지만 모든 표준이 항상 실용적이었던 건 아닙니다.

 

J2EE에는 EJB라는 스펙이 존재합니다. EJB(Enterprise Java Beans)란, 분산 애플리케이션을 지원하는 컴포넌트 객체입니다. 즉 EJB를 활용하면 내 컴퓨터의 객체가 다른 컴퓨터의 객체와 통신을 할 수 있다는 이야기입니다. 그리고 이런 객체들을 관리하는 EJB 컨테이너라는 것도 존재했는데, EJB 컨테이너는 분산 트랜잭션 지원 등의 업무를 대신 수행해줬습니다.

 

EJB는 초기에 실용적으로 보였고 많은 사랑을 받았습니다. 하지만 EJB 표준에 맞춰서 개발을 진행하다 보니 순수한 비즈니스 로직에 집중하기는 커녕 EJB 컨테이너 기술들을 위해 상투적인 코드를 작성해야 했고, 특정 EJB 컨테이너에 종속적인 코드를 작성할 수 밖에 없었습니다. 이는 유지보수성에 있어 많은 문제를 불러왔고, 흔히 이 시기를 '추운 겨울'이라고 표현하기도 했습니다.

Spring

이처럼 J2EE 표준을 준수한 애플리케이션들이 너무나도 복잡해지니 로드 존슨이라는 사람이 이런 문제점을 해결하기 위한 방법을 제시했는데, 그것이 바로 스프링입니다. 다만 스프링은 J2EE 표준을 대체하기 위해 등장한 것은 아니며, J2EE 사양과 통합을 하는 것이 목적인 프레임워크입니다.

 

이런 스프링의 등장으로 '추운 겨울'이 지나가고 '봄(Spring)'이 오기 시작했습니다. 스프링은 EJB와 달리 순수한 POJO(Plain Old Java Object)를 개발할 수 있도록 지원하는 프레임워크이기 때문에, 스프링을 사용하는 개발자들은 어떤 기술에도 종속되지 않는 순수한 비즈니스 로직을 작성할 수 있게 되었습니다. 이는 테스트하기도 간편했으며 확장하기도 수월했습니다. 스프링은 기술의 영역을 비즈니스의 영역으로부터 성공적으로 분리해냈습니다.

 

그리고 스프링을 사용하면서 복잡한 서블릿 컨테이너 구성과 다양한 설정들을 간소화하고자 하는 요구가 생겨났는데, 그 요구에 따른 결과물이 바로 스프링 부트입니다.

 

마치면서

웹 어플리케이션의 시초격이라 할 수 있는 CGI부터 스프링에 이르기까지의 흐름을 살펴보았습니다. 현재 우리가 사용하고 있는 기술의 역사를 이해하는 것은 중요한 역량이라는 생각이 드는 것 같습니다.

 

혹시 부족한 내용이 있거나 고쳐야 할 부분이 있다면 피드백 남겨주세요! 

 

감사합니다.

참고 자료

The Spring Framework - Nico Mommaerts, Piter Degreauwe

Spring framework overview

[Server] CGI와 Servlet에 대해서

JSP와 Servlet(서블릿) 비교

스프링 프레임워크의 탄생 배경

구구의 웹 어플리케이션 발전 과정 강의