일단 프레임은 틀이라는 뜻이고, 워크는 일을 하다라는 뜻이다. 즉 프레임워크는 틀안에서 특정 일을 하는 것을 말한다. 프레임워크는 틀 안에서 벗어나 작업하지 말고, 제공된 틀에 맞춰 개발하는 것이 프레임워크이다.
스프링은 오픈소스이다.
오픈소스라는 건 소스코드가 공개 되어있다는 뜻이다. 우리는 스프링이 어떻게 만들어져 있는지 내부를 볼 수도 있고, 뜯어 고칠 수도 있다. 스프링에 대해 아주 깊은 곳까지 학습하게 되면 우리가 불편하다고 생각하는 부분을 고쳐 컨트리뷰트도 할 수 있다. 즉, 스프링은 무료라는 뜻이다.
스프링은 IoC 컨테이너를 갖고 있다.
IoC(Inversion of Controll, 제어의 역전)는 스프링의 핵심 그 자체이다. 제어를 역전한다는 것은 무슨 말일까? 주도권을 빼앗겼다는 뜻이다. 쉽게 말해 주도권이 스프링에게 있다는 것.
Java에는 Class(설계도), Objcet(실체화가 가능한 어떤 것), Instance가 있음.
가구라고 하는 추상적인 것이 있다고 가정해보자. 우리는 의자나 책상 따위를 가구라고 부르지만, 가구 그 자체인 물체는 없으므로 가구는 추상적인 것이다. 반면에 의자나 책상은 실제로 우리가 사용하고 만지고 볼 수 있는 것들이다. 의자나 가구는 오브젝트(Object)이다.
각각의 클래스에서 의자나 책상이라는 오브젝트를 매번 만들기 힘들기 때문에 스프링은 이러한 오브젝트를 직접 관리해준다. 그리고 heap 영역에 저장되어 있던 객체들을 불러와 사용하게 해준다.
스프링은 DI를 지원한다
앞서 말한 것처럼 스프링은 IoC를 통해서 객체들을 메모리에 저장해뒀다가 초기에 스캔해서 필요할 때 가져와 사용할 수 있게 해준다. 그럼 어떻게 가져올 수 있는 걸까? 스프링은 DI(Dependency Injection, 의존성 주입)를 지원하기 때문에 가능하다. 각 클래스에서 객체를 가지고 올 때, 메모리에서 서로 다른 주소의 객체를 가지고 올까? 아니다. 다 같은 주소에서 가지고 온다. 즉, 스프링이 관리하는 객체들은 싱글톤으로 관리된다. 스프링이 스캔을 하면 메모리에 초기에 한번만 뜨고, 이후에는 계속해서 공유해 사용한다.
스프링에는 굉장히 많은 필터가 존재한다.
보통 톰캣을 거쳐서 스프링 컨테이너에 접근하게 되는데, 톰캣에 접근하기 위해서는 권한이 필요하다. 이때 권한 여부를 따져주는 게 filter이다. 스프링 컨테이너에서는 인터셉트라고 하는 걸로 권한 여부를 따져 물을 수 있다.
스프링은 굉장히 많은 어노테이션을 가지고 있다.
개발을 하다가 코드와 관련된 멘션을 남겨야 할 때 우리는 주석(Comment)를 사용한다. 어노테이션도 살짝 비슷하다. 컴파일러에게 주석과 같이 무언가 힌트를 주고자 할 때, 어노테이션을 달아 컴파일러가 무시하지 않고 파악한 후 지나가게 하는 역할을 한다. 주석의 경우에는 컴파일러가 무시하고 지나간다.
스프링에서는 어노테이션을 통해서 주로 객체 생성을 한다. 리플렉션은 런타임 시에 해당 클래스가 어떤 메서드와 필드, 어노테이션을 가지고 있는지 분석 후에, 특정 행동을 하도록 한다.
스프링은 MessageConverter를 가지고 있으며 기본값은 현재 Json이다.
자바 객체를 다른 언어로 전달하려고 할 때, 또는 반대로 전달 받으려고 할 때, MessageConverter가 해당 데이터를 JSON으로 변환 하거나, 변환 받아주는 역할을 한다.
다른 언어로부터 전달 받은 JSON 객체를 MessageConverter는 자바 객체로 변환해주는 역할도 한다.
즉, 우리는 자바 객체를 다른 곳으로 던지면, MessageConverter가 알아서 JSON으로 변환해주고, 전달 받은 JSON을 자바 객체로 변환해주니 그냥 자바 객체만 던지면 된다는 이점을 갖고 있다.
스프링은 BufferedReader와 BufferedWriter를 쉽게 사용할 수 있다.
InputStreamWriter를 사용해서 데이터를 받을 수 있지만, 배열의 크기를 정해놔야 하기 때문에 적은 량의 데이터를 받을 때는 그만큼 낭비가 된다.
BufferedWriter, BufferedReader를 사용하게 되면 가변길이만큼 문자열을 주고 받을 수 있기 때문에 낭비되는 데이터가 없다.
스프링에서는 ResponseBody, RequestBody라고 하는 어노테이션을 사용하게 되면 Buffer를 쉽게 사용할 수 있다.