Spring
1. 스프링이란 무엇인가?
‘스프링은 엔터프라이즈급 자바 어플리케이션 개발을 도와주는 경량 오픈소스 어플리케이션 프레임워크이다.’
-
엔터프라이즈급 어플리케이션
엔터프라이즈급 어플리케이션은 일반 어플리케이션과 무엇이 다를까? 사실 우리가 토이 프로젝트로 만드는 쇼핑몰이나, 쿠팡이나 기능면에서는 큰 차이가 없다. 로그인/회원가입을 필두로 하는 유저 권한 관리 기능, 상품DB와 구매DB CRUD, 검색과 필터, 기본적인 페이지 관리, 여기에 좀 더 추가를 하면 채팅 기능까지. 토이 프로젝트 수준에서는 한명의 개발자가 시간만 주어진다면 충분히 만들 수 있는 기능들이다.
그렇지만 쿠팡에는 수백명의 전업 개발자들이 열심히 개발을 하고 있다. 즉, 실제 엔터프라이즈급 어플리케이션이라면 그 수많은 유저들의 트래픽을 처리하고, 절대 뚫려서는 안되는 네트워크 보안을 설계하고, 트랜젝션을 관리하고, 분산 처리를 지원하고, 모듈간 결합도를 낮추는 DI기법을 지원하고… 이렇게 어플리케이션의 규모가 커지면 개발할 때 고려해야하고, 문제가 발생하는 부분들이 기하급수적으로 증가한다.
따라서 이런 Dependency Injection, transaction management 등의 기능들을 미리 구현해 놓은 프레임워크의 필요성이 대두되었다. 사실 스프링 이전에 자바 EE 버전에서는 이미 위 기능들이 구현되어 있었다. 하지만 그 당시 자바 EE는 오라클이 홍보하던 내용과는 달리 설정과 관리가 상당히 까다로웠고, 프레임워크 자체도 무거웠으며, EJB (자바EE DI 관리 프레임워크) 퍼포먼스도 좋지 못하였다.
이런 자바 개발자들의 갈증을 해소시켜주는 오픈소스 프레임워크가 등장하였으니, 그것이 바로 Spring이다.
-
어플리케이션 프레임워크
일반적으로 프레임워크는 어플리케이션의 특정 계층이나, 한 가지 분야에 특화된 목표를 가지고 만들어진다. nodejs 기반 프레임워크인 express는 웹 어플리케이션, 그 중에서도 Controller 계층을 쉽게 구현하기 위한 목표를 가지고 만들어졌고, ReactJS는 웹 presentation 레이어를 위한 프레임워크이다.
하지만 스프링은 자바 어플리케이션의 전 영역을 포괄하는 범용적인 프레임워크이다. 따라서 우리는 스프링을 ‘어플리케이션 프레임워크’ 라고 부른다.
이는 스프링이 만들어진 기원과도 관련이 깊다. 스프링의 기원은 로드 존슨이라는 뛰어난 자바 엔터프라이즈 어플리케이션 개발자가 쓴 “Expert One-on-One J2EE Design and Development” 라는 책에서 시작한다. 이 책은 자바 엔터프라이즈급 어플리케이션 개발 전반에 관한 아키텍트와 전략에 관한 책으로, 저자는 “항상 프레임워크 기반으로 접근하라” 라는 전략을 강조하였다. 단순히 이를 강조했을 뿐만 아니라, 실제로 예제 어플리케이션 프레임워크 코드를 제공하였다. 이 코드가 너무 좋아서 많은 개발자들이 포럼에 모여 이 코드를 바탕으로 실제 오픈소스 프레임워크를 만들기 시작하였고, 이것이 이후에 스프링이 되었다.
스프링은 자바 엔터프라이즈 어플리케이션 개발 전 영역을 관동하는 프로그래밍 모델과 개념을 바탕으로, 각 영역에 필요한 프레임워크들을 제공하고 있다.
현재 스프링 프레임워크에는 22개의 스프링 프로젝트들이 포함되어있다. 웹 MVC, DB/ORM, AMQP, batch 등 수많은 영역에 스프링의 기본 개념이 적용된 하위 프레임워크들이 존재한다.
-
경량 (light-weight)
스프링이 경량급 프레임워크라는 말은, 스프링 자체가 가벼운 프레임워크라는 말이 아니다. 위에서도 말했듯 스프링은 엔터프라이즈급 자바 어플리케이션 전반에 사용되는 20여개의 하위 프레임워크들의 집합으로, 수십만 라인에 달하는 코드를 가진 매우 복잡하고 거대한 규모의 프레임워크이다.
그럼에도 스프링이 경량급이라는 말은, 스프링의 자리를 차지하고 있었던 자바 EE에 비해 불필요한 무거움이 줄었다는 의미일것이다. 자바 EE는 그 당시 개발 환경과 운영 서버, 빌드/테스트 사이클, 실제 작성된 코드 등이 모두 무겁고 복잡하였다. EJB를 돌리기 위해서는 고가의 무겁고 복잡한 WAS 프로그램이 필요했다.
그에 비해 스프링은 가장 단순한 WAS인 톰캣이나 제티에서도 잘 동작하였다. 서블릿 컨테이너만으로 충분하니 복잡한 환경이나 고가의 WAS를 쓸 필요가 없고, 개발 자체도 단순해진다. 그럼에도 불구하고 자바EE 에서 제공하던 모든 기능들을 더 편하게 쓸 수 있었다. 그렇기에 스프링은 군더더기 없는 경량급 프레임워크라고 불리게 된 것이다.
2. 스프링의 목적
스프링은 그 기능과 API 사용 방법을 잘 안다고 해서 잘 쓸 수 있는 게 아니다. 스프링의 목적을 잘 이해하고, 또 스프링이 어떤 접근 방법으로 그 목적을 달성하려 하는지를 이해해야 한다. 우선 스프링의 목적은 ‘엔터프라이즈 개발을 편하게’ 만들어 주는 것이다.
-
엔터프라이즈 개발의 복잡함
엔터프라이즈 개발은 편하지 않다. 사실 무척이나 복잡하다. 왜 그럴까? 크게 두 가지 원인을 생각해볼 수 있다.
- 기술적인 복잡함
우선 위에서도 설명했듯, 엔터프라이즈급 어플리케이션의 규모는 점점 커지고, 다루는 데이터와 돈의 양이 갈수록 많아지고 있다. 이제는 대부분의 사람들이 은행 업무를 어플리케이션으로 처리하고, 모든 사람이 채팅 어플리케이션으로 대화를 하며, 동영상 스트리밍 어플리케이션으로 콘텐츠를 소비하고, 쇼핑 어플리케이션으로 물건을 구매한다. 엔터프라이즈급 어플리케이션은 점점 늘어나고, 고려해야 하는 기술적 문제도 많아지고 복잡해진다. 단순히 비즈니스 로직을 처리하는 것 뿐 아니라, 많은 트래픽이 몰려도 분산해서 처리할 수 있는 기술, 유저가 늘어남에 따라 쉽게 확장할 수 있어야 하고, 트랜젝션도 당연히 지원되어야 하며, 보안도 신경써야 한다.
- 비즈니스 로직 자체의 복잡함
이전에는 생각도 하지 못했던 비즈니스가 IT를 기반으로 진행되고 있다. 어플리케이션을 이용해서 택시를 잡고, 소개팅 상대를 추천 받을 것이라고 십년, 이십년 전에 누가 상상이나 했을까? 이런 소비자용 어플리케이션 뿐 아니라 기업 내부 업무용 어플리케이션까지, 점차 어플리케이션이 처리해야 하는 비즈니스 로직 자체도 복잡해져만 간다.
혼재된 두 가지 복잡함
더 큰 문제는 비지니스 로직과 기술적인 로직이 어플리케이션 내에서 서로 섞여 있다는 점이다. 하나를 다루는 것도 쉽지 않은 일인데, 두 가지를 동시에 다루어야 하니 그 복잡함이 두배가 아니라 세 배, 네 배로 증가하는 것이다. 두 가지 로직을 완전히 분리할 수 있으면 좋겠지만, 스프링 등장 이전의 자바 어플리케이션 개발 기법은 이 두가직 로직이 서로 혼재될 수 밖에 없는 방식이었다.
-
복잡함을 해결하려는 노력
사실 점점 더 많은 비지니스가 IT 기반으로 전환되고, IT 서비스가 거대해 지는 것은 개발자 입장에서는 반길 만한 일이지, 문제라고 볼 수는 없다. 그렇다고 구현/유지보수가 어려우니 비지니스 로직을 좀 단순화 하라거나, 보안을 좀 허술하게 할 수는 없는 노릇 아니겠는가?
그렇다면 개발자들이 이 복잡함을 조금이라도 낮추기 위해서 집중해야 할 부분은 기술적 복잡함과 비지니스 로직을 최대한 분리해내는 일일 것이다.
실패한 해결책: EJB
자바 EE에서 제안했던 EJB라는 해결책 역시 이 두가지 복잡함을 분리하려는 목표를 가지고 있었다. 결과적으로 말하면 EJB는 실패한 해결책이었다. 비지니스 로직에서 기술적인 복잡함을 어느 정도 분리해내기는 했지만, 오히려 EJB라는 환경에 종속적인 코드를 짜도록 강제하였다. 더 큰 문제는, EJB 의 요구사항을 맞추기 위해 객체지향이라는 자바의 장점을 상당 부분 포기해야만 했다는 점이다.
비침투적인 방식을 통한 해결책: 스프링
EJB는 자바 코드에 침투하여 개발자가 원하는 코드를 마음대로 개발하지 못하게 방해했다. 스프링은 DI로 대표되는 비침투적 기술을 사용하여, 최대한 개발자의 비즈니스 로직에 스프링 관련 코드가 등장하지 않도록 하였다.
이는 성격이 다른 두 복잡함을 효과적으로 분리하면서도, 자바 언어가 지닌 장점을 훼손하지 않을 수 있게 만들었다.
-
복잡함을 상대하는 스프링의 전략