2020. 1. 26. 18:27ㆍProgramming/WebProgramming
들어가며
취준생 시절 때부터도 쭉 간직해 온 의문이 있었습니다. 내로라하는 대기업들의 구직 공고를 보면, 항상 따라오는 조건들이 있었죠.
- Java 언어 사용이 능숙한 분
- Spring Framework 개발 경험이 있으신 분
Java를 배우긴 했지만, 백엔드에 사용해본 적은 없었기에 이 부분은 항상 지원에 걸림돌이 되곤 했습니다. 도대체 자바 스프링이 뭐하는 녀석이길래 이 기업 저 기업에서 다 찾을까요? 나름대로 정리한 내용을 글로 옮겨보기로 했습니다. 그리고 '그렇다면 Spring을 배워야만 할까?' 하는 고민에 빠지신 분들께 제 의견을 전달해보고자 합니다.
주의사항 : 필자는 백엔드 개발에 이제 막 뛰어든 초짜입니다. 백엔드의 유구한 역사에 대해서는 당연히 잘 모르며, 제가 추측한 이유들도 잘못된 부분이 있을 수 있음을 밀리 알려드립니다.
Spring이 뭔가요?
백엔드에 입문하는 사람들에게 스프링이 가장 큰 장벽으로 다가오는 원인은 바로 장황함에 있다고 봅니다. 자료조사를 시작하는 순간부터 '의존성 주입(Dependency Injection)'과 '역전 제어(Inversion Of Control)' 등의 생소한 개념들이 다가오고, gradle 설정, application.properties 수정하기 등의 작업이 들어가면 정말 당혹감을 느끼지 않을 수가 없습니다. 실사용 전에 개념만 가지고도 책 한권 분량은 족히 뽑아낼 수 있습니다. 물론, 이러한 개념들이 바로 스프링이 백엔드 개발에서 주류이자 현역으로 남아있는 가장 큰 이유라고 봅니다만, 요즘 백엔드 입문은 node.js express같은 가벼운 프레임워크로 시작하는 게 기본이다 보니, 개발 입문자들에겐 큰 장벽처럼 느껴지기 마련입니다. 그러다 보면 '아니 자바 스프링이 뭐길래 이 편한 노드 익스프레스 놔두고 이것만 고집하는거야?' 라는 생각이 떠오르게 되는 것이죠.
간단하게 요약하자면 Spring 프레임워크는 Java Enterprise Edition(기업용 자바)의 한계점을 극복하기 위한 배경에서 등장한 프레임워크입니다. 자바가 초창기에 서버로 활용될 때에는 자바 EE를 사용했었는데, 자질구레한 문제점들이 있었고, 로드 존슨이라는 인물이 이를 개선하기 위해 제안한 것이 바로 스프링 프레임워크입니다. (그래서 이름도 겨울이 끝나고 '봄'이 왔다는 뜻에서 Spring이다.. 라고 알고 있습니다) 결론은, 현재 자바로 백엔드 개발 == 자바 스프링 or 자바 스프링부트 라고 봐도 무방합니다.
자바 EE와 스프링과의 관계를 자세히 설명한 글이 있어 여기에 링크합니다. (잘 몰라서 도망가는 거 아님.. ㅎㅎ.. ㅈㅅ.. ㅋㅋ!!)
왜 다들 Spring을 쓰나요?
1. 정적 타입 언어로서의 강점
앞서 말한, 자바 스프링의 라이벌(?)쯤 되는 존재로 node.js의 express를 언급을 했습니다. Python에는 Django와 Flask가 있죠. 익스프레스는 간편한데, 자바는 왜 이렇게 복잡하다고 느껴질까요? 여러가지 이유가 있겠지만 가장 큰 이유는 자바스크립트가 동적 타입 언어이기 때문입니다.
위의 짤은 정확히는 '동적 타이핑'과 100% 일치하는 짤은 아니지만, 어느정도 연관성이 있습니다. 아래같은 코드를 볼까요.
const arr1 = [1, 2, 3, 4];
const arr2 = ['1', '2', '3', '4'];
const reduceArr = arr => arr.reduce((left, right) => left + right);
reduceArr(arr1); // 10
reduceArr(arr2); // '1234'
reduceArr는 배열 안의 원소들을 전부 더해주는 함수입니다. 개발자는 모든 숫자를 더해주는 함수를 의도하고 만들었으니, arr1 같은 배열이 원소로 들어간다면 정상적으로 10이 출력이 됩니다. 그러나 실수로 arr2 같은 문자열 배열이 들어갈 경우엔 concat이 발생하여 '1234'가 되어버립니다. 자바스크립트에서는 이를 미연에 감지하고, 막을 방법이 없습니다.
반면에, 자바는 정적 타이핑을 사용하므로 어느 정도 커버가 가능합니다.
public int reduceArr(int[] arr) {
int result = 0;
for (int e : arr) {
result += e;
}
return result;
}
final int[] arr1 = new int[4] { 1, 2, 3, 4 };
final String[] arr2 = new String[4] { "1", "2", "3", "4" };
System.out.println(reduceArr(arr1)); // 10
System.out.println(reduceArr(arr2)); // 말도 안되는 호출이므로 바로 빨간줄 그어짐
자바는 함수의 입력과 출력이 어떤 타입을 가져야만 하는지를 강제합니다. 그러므로 위의 사례같은 잘못된 호출을 최대한 막을 수 있습니다. 특히나, 이런 장점은 다른 사람들과 협업할 때, 혹은 오랜 시간 동안 작업할 때 부각이 됩니다. 10명이서 동시에 작업하는 프로젝트에서, 다른 사람이 작성한 모든 코드를 숙지하며 올바르게 사용할 수 있을까요? 혹은, 반년 전의 내가 작성한 코드를 현재의 내가 100% 다 기억한다는 보장이 있을까요? 이런 이유 때문에 규모 있는 서비스 개발에는 정적 타입 언어가 선호됩니다.
그러나 이는 스프링이 주류인 충분한 이유가 되지 못합니다. 왜냐하면, js 진영도 이 부분을 잘 알기에, TypeScript라는 언어를 내놓았기 때문이지요. 동적 타이핑에 대한 약점은 TypeScript의 사용으로 충분히 커버하고도 남습니다. "타이핑 때문에요? 자바스크립트도 충분히 잘 되는데요?"
2. 컴파일된 언어로서의 장점
자바가 js, 파이썬이 가진 공통점은 가상 머신(VM) 기반으로 작동된다는 점이고, 이 중에서 자바가 다른 언어들과 구별되는 가장 큰 특징은, 자바는 컴파일된다는 점입니다. 프로그래밍을 입문하면 배우는 사실이지만, 프로그래밍 언어는 사실 컴퓨터가 전혀 알아먹을 수 없는 외계어에 해당합니다. 컴퓨터는 '기계어'만 이해할 수 있으므로, 모종의 과정을 통해 컴퓨터에게 기계어를 넣어줘야만 합니다. 컴파일러는 "미리 번역해서 기계어로 만들어버리자"라는 개념이고, 인터프리터는 "한 줄 한 줄 읽어가면서 기계어로 통역(interpret)해주자"라는 개념(그래서 js와 파이썬은 자바와 다르게 REPL이 가능합니다.)입니다.
설명을 읽어봐도 느낄 수 있지만, 컴파일러가 인터프리터보다 압도적으로 빠릅니다. 특히나 컴파일 과정에서는 소스 코드를 먼저 읽어보는 과정에서, 문법 에러를 감지하기도 하고, 최적화를 수행하기도 합니다. '어, 이 코드... 다르게 바꾸면 똑같은 동작이지만 성능은 더 좋아지겠는데?' 하면서 바꿔치기하는 과정까지 들어가는 것이죠. 엄밀히 말하면 자바는 기계어가 아니라 JVM(자바 가상머신)이 이해하는 '바이트 코드'로 변환되므로 C, C++에 준하는 성능까지는 절대 나오지 않습니다. 그러나 그렇더라도 인터프리터 언어보다는 빠르다고 할 수 있죠.
...라고 설명했습니다만, 이 또한 자바가 주류인 이유로서는 부적합합니다. 왜냐하면, 파이썬, 노드 같은 언어들도 이제는 JIT 컴파일을 지원하므로 실행 전에 컴파일이 수행되게 할 수 있습니다. 맥에서 PyCharm을 사용해보면 .pyc 를 생성하는 것을 볼 수 있는데, 이는 파이썬 실행 전에 이미 한번 컴파일을 수행한다는 의미입니다. "컴파일이요? 요즘엔 다른 언어도 다 하는데요?"
3. Spring이 제공하는 걸출한 도구들
사실 1, 2번은 "자바를 왜 쓰냐"에 해당합니다만, 스프링 프레임워크의 특성도 짚고 넘어가야 할 것 같습니다. 스프링은 자바 EE를 개선하기 위한 움직임에서 나온 프레임워크라는 언급을 했었습니다. 그런 배경이 있는 만큼, 기업이 애플리케이션을 만들 때 필요한 도구는 거의 다 갖추고 있다고 봐도 무방합니다.
Spring Security
- 인증에 관한 라이브러리, 로그인과 회원 가입, 적정 유저의 접근 권한 등을 관리하며, 소셜로그인이라 불리는 OAuth도 지원합니다.
- node.js일 경우, passport라고 불리는 서드 파티를 받아서 사용해야 합니다.
Spring Jdbc
- DB 접속에 관한 라이브러리. DB 커넥터를 바꿔가면서 사용할 수 있습니다. 즉, mysql을 쓰다가 oracle DB로 변경할 일이 있더라도, 인터페이스는 변하지 않으므로 코드 변경점이 크지 않습니다.
- node.js일 경우, mysql을 사용하고 싶다면 mysql2 라는 서드파티 패키지를 사용해야 합니다. DB를 바꾸고 싶다면 아예 다른 패키지를 받아야 합니다.
Spring Actuator
- 해당 웹 서버의 헬스 체크(Health Check), 모니터링 등을 도와주는 라이브러리입니다.
- node.js에서는 이 경우 어떤 것을 주로 채택하는 지 잘 모르겠습니다.
그 외에도 Spring 생태계에서는 필요에 따라 쓸 수 있는 다양한 라이브러리가 있으며, 기업 차원에서 이 라이브러리에 기여하기도 합니다. Spring Cloud Netflix가 대표적 예입니다.
이 비교에서 node.js express가 안 좋다고 말하는 것이 아닙니다. node.js의 npm을 보면 정말 무수히 많은 서드 파티 라이브러리가 있습니다. 노드의 강점은 바로 이 풍부한 라이브러리 생태계입니다. npm의 주류 라이브러리들은 무수히 많은 컨트리뷰션으로 유지되고 있으므로 지원 중단을 걱정할 일은 없습니다.
그러나, Spring은 기업의, 대규모 서비스에서 사용되고 있음을 상기할 필요가 있습니다. "단 1초라도, 단 한 명이라도 장애를 겪어서는 안 된다"는 입장에서는, 아직 써보지 않은 제 3자의 라이브러리를 선정해 모험을 감수하는 것보다는 이미 수많은 기업이 사용함으로써 검증된 라이브러리를 사용하는 것이 더 합리적인 선택일 것입니다.
그러나 이 논리대로라면 전 세계에서 규모 좀 있다는 모든 기업이 다 Spring을 써야 정상입니다. 그러나 페이스북은 PHP를 개량하여 사용하고 있고, 드롭박스는 파이썬으로 돌아가고 있습니다. 트위치는 루비 온 레일즈(Ruby On Rails)로 돌아갑니다. 국내에서 이 위의 세 회사보다 더 많은 트래픽을 감당중인 회사가 얼마나 있을까요? 근본적인 이유는 바로 다음과 같습니다.
4. 개발자 구인의 용이성
사실, 어느 트래픽에 어느 언어를 써야만 한다는 정답은 없습니다. 실력 있는 개발자만 있으면 세상 그 어느 언어를 갖다 놔도 매우 잘 돌아가도록 할 수 있습니다. 자바 스프링이 타 언어들에 비해 안정성이 있다거나, 성능이 잘 나온다 등의 이유가 있더라도, 국룰처럼 항상 채택될 이유가 되진 않습니다. 국내 시장에서 자바 스프링이 자주 보이는 것은, 경력자 구하기가 용이하기 때문입니다.
자바가 도처에서 적극 활용된 지는 꽤 오랜 시간이 지났습니다. 처음에는 "가상 머신 기반이라 속도가 너무 느리다"는 악평을 받았지만, 가상 머신 기반으로 작동한다는 장점이 잘 먹혀 들어가, 전세계에서 사랑받는 언어가 되었습니다. 가까운 예만 보더라도 안드로이드가 있죠. 현재는 Kotlin으로 전환 중이지만, 이 코틀린마저도 JVM 기반의 언어이므로 '자바 진영'으로 볼 수 있습니다.
한국 IT도 한 때 자바 열풍이 불어 적극 활용되었고, 당시 IT 인력 양성에서도 C++ 못지 않게 자바가 대세였다고 합니다. 여기에 쐐기를 박는 것이 전자정부프레임워크인데, 자바 스프링 기반으로 만들어진 이 전자정부 프레임워크 때문에 직간접적으로 공공기관과 관련된 일을 해야하는 회사들이 자바를 이용할 수밖에 없었습니다. (국내 IT 시장에서 흔히 알려진 대기업과, 잘 알려지지 않은 SI 기업 중 어느 쪽의 수가 더 많을지 상상해 봅시다.) 이런 여러가지의 흐름 덕에 IT 시장에서 자바 개발자의 수는 많아졌고, IT 사업이 점점 커지면서 기업들이 경력자를 많이 필요로 하게 되고, 그 결과 많은 경력자들이 애용하는 자바 스프링이 국내 IT 시장의 대감마님이 되었습니다.
다들 Spring만 쓰는 건 아닙니다.
본문에 길게 설명하긴 했지만, 결론은 "Spring을 꼭 써야만 해서 쓰고 있는 것은 아니다"는 것을 느끼실 수 있을 듯합니다. 스타트업 중에서 자바 스프링을 채택하는 곳은 드뭅니다. "빠른 시간 내에 어떻게든 결과물을 내야하는 상황"에서 자바는 썩 좋은 선택은 아닙니다. 동적 타입 언어는 다소 예측하지 못한 문제들을 낳을 지는 몰라도, 생산성에서는 다른 언어들과 차원이 다릅니다. 그래서 대기업이 아닌 기업들을 볼 경우에 파이썬 Django나 노드 Express를 쓰는 경우를 자주 볼 수 있습니다. 어떤 기업은 Spring 프레임워크의 한계를 느껴서 다른 언어로 전환하기도 합니다.
신입으로 들어가려면 Spring을 배워야 하나?
제 의견은, '그럴 필요 없다'입니다. 물론 미리 배워두면 입사 후 적응이 빠를 수는 있겠지만, Spring 자체에 목을 매달 필요는 없습니다. 프레임워크는 어디까지나 도구입니다. 백엔드 개발에서 중요한 본질은 "네트워크 개념을 얼마나 잘 이해하고, DB를 얼마나 잘 이해하고, 이를 어떻게 응용할 수 있는가"입니다. 이 부분만 잘 숙지가 되어있다면, 프레임워크는 그 다음 문제입니다. 지금 쓰고 있는 프레임워크가 언젠가는 사멸(?)할 지도 모른다는 생각으로 접근해야 합니다. 상상하기 어렵지만, 언젠가 자바 스프링이 저무는 때가 오더라도, 백엔드에 대한 핵심 개념을 잘 간직하고 있다면, 어렵지 않게 다른 프레임워크를 집어들 수 있겠죠.
그렇기 때문에 기업에서는 신입에 대해 특정 프레임워크의 숙달도를 크게 신경쓰지 않습니다. (거기에 연연하는 기업이라면 저는 차라리 가지 말라고 말씀드리고 싶습니다.) 기존에 연습하던 것들, 하고 있던 프로젝트를 고도화해서 백엔드 지식을 많이 쌓은 상태라면, 마땅히 면접보는 사람들은 '개념을 이 정도로 알고, 이런 경험까지 해봤다면, 입사해서 스프링으로 전환하는 것도 금방 하겠군' 이라고 예상을 하게 될 것입니다. 그러니 "기존에 하던 것을 버리고 스프링을 다시 배울까?"가 고민된다면, 전 차라리 "지금 하던 걸 더 깊게 파서 수준 높은 경험을 쌓으세요" 라고 말씀드리고 싶습니다.
마치며
국내 IT 시장에서의 Spring의 위상(?)은 제 오랜 시절 궁금증이기도 했고, 가장 큰 골칫거리이기도 했습니다. Spring 경험이 아예 없는 상태로 인턴을 들어갔고, 입사까지 하게 되면서 이 두려움을 떨쳐낼 수 있었는데, 저의 경험이 비슷한 백엔드 개발 입문자들에게 하나의 인사이트를 던져주는 계기가 되었으면 하는 마음에 이 글을 작성해보았습니다. Spring에 대한 저의 생각이 많이 왜곡되어 있을 수도 있습니다. 저는 이 업계에 발을 들인지 이제 반년을 넘겼으니까요. 잘못된 정보가 있다면 언제든지 정정해주시면 감사하겠습니다.