김대용
Spring

스프링 프레임워크는 왜 등장했을까?

--------------------

스프링과 스프링 프레임워크는 한국 뿐만 아니라 세계에서 가장 인기있는1 자바 프레임워크일테다. 이렇게 인기가 있어진데에는 이유가 있다.

  1. 기업에서도 쓸만한 오픈소스 프레임워크
  2. 스프링 프레임워크를 기반으로한 수많은 프로젝트들(스프링 웹, 배치, 시큐리티 등)을 활용한다면 해야하는 일은 줄고, 생산성이 높아진다.
  3. 적당한 난이도와 진입장벽, 그에 따른 많은 개발자 공급

기업들 사이에서 인기가 많아지면서 막연히 스프링을 도전하려는 사람들도 많아졌다. 새로운 기술을 도전하는 건 언제나 환영이다. 그러나 잠깐, 스프링의 세계에 뛰어들기 전 한발짝 물러나 큰 그림을 보고가자. 스프링 프레임워크는 왜 만들어졌을까? 스프링이 있기 전에는 무슨 프레임워크, 기술을 사용했을까?

닷컴 버블과 자바

자바는 닷컴 버블과 함께 가장 수혜를 많이 받은 언어가 아닐까 싶다. 너도나도 자바를 쓰면서 인기가 급부상했고, 엔터프라이즈 영역의 확장까지 성공적으로 이뤄내면서 아직까지도 자바 생태계는 활발히 발전하고 있다. 간단하게 자바가 어떻게 등장했는지, 어떤 과정을 거쳐 발전했는지 빠르게 살펴보자.

브라우저 등장과 스크립트 언어의 필요성

1990년, 최초의 브라우저가 등장했고, 93년 최초로 이미지를 띄울 수 있는 '모자이크' 브라우저의 등장 및 WWW 붐으로 웹 생태계가 빠르게 발전해갔다. 초기 웹은 정적인 컨텐츠들 밖에 볼 수 없었다. 그래서 모자이크 제작사 넷스케이프는 이를 극복하고자 스크립트 언어를 도입하려했다. 넷스케이프는 두가지 루트를 택했는데, 첫번째로 자신들만의 언어를 만드는 것, 두번째로는 동적인 HTML을 그려낼 수 있는 웹브라우저 데모를 만든 회사와 협력하는 것이였다. 이는 각각 자바스크립트(95년 12월)와 자바(95년 6월)의 탄생으로 이어졌다.2

자바와 자바스크립트의 어원

클라이언트용 언어로 각광받은 자바와 자바 애플릿

사실 자바는 1990년 Sun 사에서 셋톱박스 개발에 쓰일 언어로 만들어졌다. 그러나 92년 케이블 티비 입찰경쟁에서 져버려 개발 중단되었다. 얼마있지 않아 93년 모자이크 브라우저가 등장하고, 자바 개발자들은 인터넷이 케이블 티비를 대체할 새로운 매체라고 생각해 간단한 브라우저 프로토타입을 만들었다.

이 브라우저는 자바 애플릿이라는 기술이 사용되었다. 당시 정적인 브라우저와 다르게 사용자 입력을 받거나 그래픽 컨텐츠들을 보여줄 수 있었다. 이에 넷스케이프 사에서 관심을 가지고 모자이크 브라우저에 자바를 지원하겠다고 발표하면서 자바는 큰 인기를 얻게 되었다.3

애플릿은 3D 컨텐츠도 표현가능해 물리학, 생물학 같은 영역에서도 유용히 사용가능했다. 당시 자바스크립트는 3D 가속 지원을 하지 않았다.애플릿은 3D 컨텐츠도 표현가능해 물리학, 생물학 같은 영역에서도 유용히 사용가능했다. 당시 자바스크립트는 3D 가속 지원을 하지 않았다.

서블릿과 EJB의 등장

자바는 브라우저와 같은 클라이언트에서 실행할 목적으로 만들었지 서버에서 실행할 목적으로 만들어지진 않았다. 그치만 Sun 사는 웹 애플리케이션 같은 서버에서 사용될 가능성을 보았고, 96년에 서블릿 API 1.0 명세를 발표했다. 서버에서 클라이언트 요청에 따라 적절한 응답을 줄 수 있게 되면서, 엔터프라이즈 영역에서 상당히 많이 사용되었다.

엔터프라이즈 애플리케이션은 거의 대부분 비슷한 문제를 해결해야했는데, 프로그래머들이 매번 코딩을 해야했다. 그래서 트랜젝션 무결성, 영속성, 보안 등과 같은 공통 영역들을 표준화할 필요가 생겼다. 이렇게 EJB(Enterprise Java Beans)라는 표준이 만들어지게되었다. 최초로 97년에 IBM이 만들었고, 이를 99년에 Sun이 자바 1.2 버전을 출시하면서 공식 채택했다.4

자바 1.2 플랫폼

1999년에 Sun은 자바 1.2 버전을 출시했다. 이는 흔히 'Java 2'라고 불렀고, 이는 세가지 플랫폼을 제공한다.

  • J2ME(Java 2 Platform, Micro Edition): 임베디드 소프트웨어(휴대폰, 가전기기 등)을 개발할 때 사용되는 플랫폼
  • J2SE(Java 2 Platform, Standard Edition): 가장 흔하게 쓰이는 플랫폼으로, 자바 코어, JVM, 표준 API 등 개발에 사용되는 키트 (JDK라 불림)
  • J2EE(Java 2 Platform, Enterprise Edition): J2SE와 함께 쓰이며, 엔터프라이즈 애플리케이션을 만들 때 사용되는 플랫폼

이전까지 흩어져있던 자바 기술과 API를 한군데에 모으려는 노력이 담긴 결과물이라고 볼 수 있다. 특히 J2EE의 경우, EJB, JSP, JDBC, JTA 등 엔터프라이즈 애플리케이션을 개발하기 위한 기능을 표준화해 여러 기술을 한데 모았다.

J2EE와 악명높은 EJB

EJB는 원래 나머지 J2EE 구성요소(JSP, Servlet, JDBC 등)들과의 통합을 쉽게 도와주는 베이스 역할을 하고, 요구사항을 구현한 핵심 비즈니스 로직과 애플리케이션을 분리해 확장, 재사용, 유지보수가 용이하게 도와주기위해 만들어진 프레임워크다. 정형화된 틀을 제공하니 코드가 간결해지고, 생산성이 높아지고, 성능도 나아지리라고 기대했지만, 실제로는 그렇지 못했다.

EJB는 오버엔지니어링의 산물이라고 생각된다. 단순한 기능을 만들기 위해서 필요하지 않은 부분까지 신경쓰고 구현해야한다. 아무리 간단하더라도 크고 복잡해질 미래를 위해서 강제로 대비하게 만든다. 예를 들어 사용하는 데이터베이스가 하나라도 여러개로 분산될 것을 대비해야한다.

스프링 개발자 로드 존슨은 "Expert One-on-One™ J2EE™ Development without EJB™" 책에 EJB에 관한 본인의 경험을 공유했다.

  • 복잡성을 줄인다기보다, 복잡성을 더 키운다.
  • 영속성을 위해 만들어진 '엔티티 빈'의 실험이 완전히 실패했다.
  • EJB를 사용한 애플리케이션은 다른 J2EE 기술을 사용한 애플리케이션보다 애플리케이션 서버간 이식성이 떨어진다.
    • (주석) J2EE는 표준이라 실제로 구현한 애플리케이션 서버는 여러 종류가 있다. 예를 들어 아파치 톰캣, JBoss EAP, GlassFish 등이 있다. EJB 자체가 워낙 복잡하기 때문에, 이 애플리케이션 서버간 호환이 잘 안될 수도 있다는 말이다.
  • EJB가 확장성의 핵심이 될 것이라는 약속에도 불구하고, EJB 시스템은 종종 성능이 떨어지며 반드시 잘 확장되는 것도 아니다. EJB 애플리케이션이 과부하가 걸린다면 내 경험상으로는 완전히 재설계해야하거나 프로젝트의 실패를 초래한다.
  • EJB는 쉬운 일을 어렵게 만든다. 예를 들어 EJB에서 싱글톤 패턴조차 구현하기가 어렵다.
  • 객체 지향적인 애플리케이션이 되기 보다, EJB/J2EE 적인 애플리케이션이 된다.

이러한 배경 속에서 로드 존슨은 'EJB 없는 J2EE 개발'을 주장했고, EJB 기능의 대안을 제시하며, 명세가 복잡하던 EJB와는 다르게 표준화가 잘되어있고 간결한 나머지 J2EE 구성요소들을 직접 사용하자고 주장했다. 그러면서 2003년 당시 떠오르고 있던 '경량' 프레임워크들을 소개하면서 자신이 최근에 만든 '스프링' 프레임워크를 소개한다.

스프링 프레임워크의 등장

스프링 프레임워크는 애플리케이션 프레임워크로, 당시 어수선하던 J2EE 시장을 단숨에 사로잡았다. 스프링은 아래와 같은 원칙을 내세웠다.

  • 다른 프레임워크가 해결하지 못하는 문제를 해결할 수 있게
    • 특정한 기능을 해결하는 솔루션은 많았지만, 이를 잘 조합해 사용하기란 매우 어렵고 번거로웠다. 스프링은 사용자가 손대지 않아도 쉽게 전문적인 프레임워크를 조합해서 사용할 수 있게 도와준다. 그래서 스프링은 특정한 기능(웹, IoC, AoP)의 프레임워크가 아닌, 이들을 통합해주는 애플리케이션 프레임워크라고 정의한다.
  • 적용이 쉽게
  • 사용하기 쉽게
  • 모범사례(Best Practice)를 적용하기 쉽게
  • 꼭 필요한 의존만 하게, 비침습성(Non-invasiveness)
  • 일관적인 설정방법
  • 쉬운 테스트
  • 확장 가능하게

스프링의 핵심 IoC 컨테이너

스프링은 이런 원칙을 지키면서 개발을 도와주는 핵심 요소로 IoC 컨테이너를 사용한다. IoC(Inversion of Control)는 제어의 역전이라는 의미로 프로그램의 흐름을 프로그래머가 아닌, 프레임워크에게 맡기는 디자인 패턴이다.5 프로그래머는 프레임워크가 실행할 코드를 일부 만들기만 하면 된다.

IoC는 흔히 할리우드 원칙이라고 부르기도 한다. 할리우드에서 배우가 되고 싶다면 에이전시에 연락을 넣지말고, 연락을 기다려라는 내용이다. ("Don't call us, we'll call you.")

IoC는 이벤트 핸들러, 콜백, 의존성 주입 등 여러가지 종류가 있다. 흐름의 주체가 프레임워크에 있는 모든 것이 IoC이다. 그 중 스프링에서 주로 말하는 IoC는 애플리케이션 객체가 필요한 다른 객체를 프레임워크가 관리하고 넘겨주는 개념, 즉 의존성 주입(DI)이다. 예를 들어 노트북이 필요해 어머니에게 사달라고 부탁하면 맥북이던, 갤럭시북이던 주는 대로 받아서 쓰는 것과 같다.

의존성 주입이 왜 중요할까? 사용하는 객체가 바뀌었을 때 프로그램 전체의 변경이 필요 없는 느슨한 결합을 추구하기 위함이다. 이는 곧 스프링의 여러가지 프로젝트(웹, 데이터, 보안 등)를 통합할 때 유연하게 적용할 수 있는 기반을 다진다는 얘기다.

이를 노트북 예제로 생각해보자. 만약 본인이 윈도우 노트북만 쓸 수 있다면, 맥북을 가져다줬을 때 쓰기 어려움을 겪는다. 윈도우 노트북만 쓸 수 있는 강한 결합이 이뤄진거다. 만약 윈도우든 맥북이든 '노트북'을 쓸 줄 안다면 어느 걸 가져다줘도 쓰는데 문제가 없다. 이렇게 '노트북'이라는 개념을 사용할 줄 아는 느슨한 결합이 이뤄진거다.

로드 존슨이 책에 언급한 '스프링이 IoC 컨테이너를 사용해 얻은 이점'은 아래와 같다.

  • 싱글톤과 팩토리를 임시로 사용하지 않아도 된다.
    • (주석) EJB은 워낙 객체 관리가 복잡했기에, 싱글톤이나 팩토리를 사용해 직접 객체를 관리했다. 그러나 이는 코드의 복잡성을 증가시키고 유지보수를 어렵게 만들었다.
  • 애플리케이션 코드를 클래스가 아닌 인터페이스를 대상으로 작성할 수 있게 돼, 올바른 객체 지향적 접근이 가능해진다. 이는 플러그 가능성과 테스트 용이성을 크게 높인다.
  • 애플리케이션 전체에 퍼진 설정을 일관되게 관리할 수 있다.
  • 테스트 용이성을 높인다. 이는 싱글톤을 제거하고, 스텁하기 어려운 API를 자주 사용하는 리소스 참고(lookup)용 코드를 사용하지 않아도 되면서 가능해졌다.

스프링 프레임워크를 중심으로한 여러 프로젝트

우리가 흔히 '스프링'이라고 부르면 두가지를 의미한다. 스프링 프레임워크 그 자체를 의미하거나, 스프링 프레임워크를 기반으로 만들어진 여러 프로젝트를 모두 일컫는다.

스프링 프로젝트는 웹, 데이터베이스, 클라우드 등 여러 분야에 걸쳐 애플리케이션 구축에 도움을 준다. 앞서 얘기했듯이 지금 필요한 것만 선택해서 프로젝트를 적용할 수 있고, 나중에 필요할 때 자유롭게 추가할 수 있다. 스프링 프로젝트 소개 페이지는 아래와 같이 말한다.

구성에서 보안, 웹 앱, 빅 데이터에 이르기까지 애플리케이션에 필요한 인프라가 무엇이든, 이를 구축하는 데 도움이 되는 Spring 프로젝트가 있습니다. 소규모로 시작하여 필요한 것만 사용하세요. Spring은 모듈식으로 설계되었습니다.

스프링 프로젝트를 더 쓰기 쉽게 돕는 스프링 부트

그러나 스프링도 설정이 복잡하기로 유명했다. 스프링을 쓰면 하루가 걸릴걸 타 언어 프레임워크로 1~2시간 안에 끝낼 수 있었다고 한다.6 그래서 스프링 애플리케이션을 만들때 반복적으로 작성해야하던 보일러플레이트 코드의 기본 셋팅을 도와주는 스프링 부트가 만들어졌다. 그것 뿐만 아니라 간편한 의존성 관리, 내장 애플리케이션 서버(톰캣 등), 보안, 메트릭, 헬스체크 등 여러 편의 기능이 추가되었다. 현재 스프링을 시작한다고하면 대부분 스프링 부트로 시작한다고 보면 된다.

마무리

스프링 프레임워크는 복잡했던 초기 J2EE를 극복하고자 만들어졌다. 스프링의 설계 원칙이 어떻게 보면 당연할지도 모르지만, 당연한 만큼 많은 고민을 거쳤을 거라고 생각된다. 당장 나도 간단한 코드를 작성할 때도 어떻게하면 더 좋게할 수 있을지 한참을 고민한다. 불편한걸 개선하고자하는 스프링 개발자들의 깊고 오랜 고민으로 만들어진 결과물 덕분에 나를 포함한 다른 개발자들의 생산성이 높아질 수 있었다.

그리고 아무리 구리거나 구려보이는 기술이라도 쉽게 비난하고 싫어하지 말자. 비판하며 어떻게 개선할지 고민해나가자. 구렸던건 사실이지만, J2EE와 EJB도 나름 시대의 어수선함을 해결하고자 나온 결과물이고, 덕분에 기술적인 발전이 가능해졌던 것이겠지.

참고

--------------------